/*******************************************************************************
* Copyright (c) 2006, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.aspectj.org.eclipse.jdt.internal.compiler.codegen;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
import org.aspectj.org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Binding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BlockScope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.FieldBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SyntheticArgumentBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeIds;
public class StackMapFrameCodeStream extends CodeStream {
public StackMapFrame currentFrame;
public ArrayList frames;
public Set framePositions;
public ArrayList variablesModificationsPositions;
public int[] stateIndexes;
public int stateIndexesCounter;
public StackMapFrameCodeStream(ClassFile givenClassFile) {
super(givenClassFile);
}
public void aaload() {
super.aaload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void aastore() {
super.aastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=3;
}
}
public void aconst_null() {
super.aconst_null();
this.currentFrame.addStackItem(TypeBinding.NULL);
}
public void addDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
// Required to fix 1PR0XVS: LFRE:WINNT - Compiler: variable table for method appears incorrect
loop: for (int i = 0; i < visibleLocalsCount; i++) {
LocalVariableBinding localBinding = visibleLocals[i];
if (localBinding != null) {
// Check if the local is definitely assigned
boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
if (!isDefinitelyAssigned) {
if (this.stateIndexes != null) {
for (int j = 0, max = this.stateIndexesCounter; j < max; j++) {
if (isDefinitelyAssigned(scope, this.stateIndexes[j], localBinding)) {
currentFrame.putLocal(localBinding.resolvedPosition, new VerificationTypeInfo(localBinding.type));
if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
/* There are two cases:
* 1) there is no initialization interval opened ==> add an opened interval
* 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
* An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
* is equals to -1.
* initializationPCs is a collection of pairs of int:
* first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
* is not closed yet.
*/
localBinding.recordInitializationStartPC(position);
}
continue loop;
}
}
}
} else {
currentFrame.putLocal(localBinding.resolvedPosition, new VerificationTypeInfo(localBinding.type));
if ((localBinding.initializationCount == 0) || (localBinding.initializationPCs[((localBinding.initializationCount - 1) << 1) + 1] != -1)) {
/* There are two cases:
* 1) there is no initialization interval opened ==> add an opened interval
* 2) there is already some initialization intervals but the last one is closed ==> add an opened interval
* An opened interval means that the value at localBinding.initializationPCs[localBinding.initializationCount - 1][1]
* is equals to -1.
* initializationPCs is a collection of pairs of int:
* first value is the startPC and second value is the endPC. -1 one for the last value means that the interval
* is not closed yet.
*/
localBinding.recordInitializationStartPC(position);
}
}
}
}
Integer newValue = new Integer(this.position);
if (this.variablesModificationsPositions.size() == 0 || !this.variablesModificationsPositions.get(this.variablesModificationsPositions.size() - 1).equals(newValue)) {
this.variablesModificationsPositions.add(newValue);
}
storeStackMapFrame();
}
public void addVariable(LocalVariableBinding localBinding) {
currentFrame.putLocal(localBinding.resolvedPosition, new VerificationTypeInfo(localBinding.type));
storeStackMapFrame();
super.addVariable(localBinding);
}
public void aload(int iArg) {
super.aload(iArg);
this.currentFrame.addStackItem(getLocal(iArg, this.currentFrame));
}
public void aload_0() {
super.aload_0();
this.currentFrame.addStackItem(getLocal(0, this.currentFrame));
}
public void aload_1() {
super.aload_1();
this.currentFrame.addStackItem(getLocal(1, this.currentFrame));
}
public void aload_2() {
super.aload_2();
this.currentFrame.addStackItem(getLocal(2, this.currentFrame));
}
public void aload_3() {
super.aload_3();
this.currentFrame.addStackItem(getLocal(3, this.currentFrame));
}
public void anewarray(TypeBinding typeBinding) {
super.anewarray(typeBinding);
char[] constantPoolName = typeBinding.constantPoolName();
int length = constantPoolName.length;
System.arraycopy(constantPoolName, 0, (constantPoolName = new char[length + 3]), 2, length);
constantPoolName[0] = '[';
constantPoolName[1] = 'L';
constantPoolName[length + 2] = ';';
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding.id, constantPoolName);
}
}
public void areturn() {
super.areturn();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
framePositions.add(new Integer(this.position));
}
public void arraylength() {
super.arraylength();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
public void astore(int iArg) {
super.astore(iArg);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(iArg, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void astore_0() {
super.astore_0();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(0, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void astore_1() {
super.astore_1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(1, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void astore_2() {
super.astore_2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(2, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void astore_3() {
super.astore_3();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(3, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void athrow() {
super.athrow();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
framePositions.add(new Integer(this.position));
}
public void baload() {
super.baload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void bastore() {
super.bastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=3;
}
}
public void bipush(byte b) {
super.bipush(b);
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void caload() {
super.caload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void castore() {
super.castore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=3;
}
}
public void checkcast(int baseId) {
super.checkcast(baseId);
VerificationTypeInfo info = null;
switch (baseId) {
case TypeIds.T_byte :
info = new VerificationTypeInfo(TypeIds.T_JavaLangByte, ConstantPool.JavaLangByteConstantPoolName);
break;
case TypeIds.T_short :
info = new VerificationTypeInfo(TypeIds.T_JavaLangShort, ConstantPool.JavaLangShortConstantPoolName);
break;
case TypeIds.T_char :
info = new VerificationTypeInfo(TypeIds.T_JavaLangCharacter, ConstantPool.JavaLangCharacterConstantPoolName);
break;
case TypeIds.T_int :
info = new VerificationTypeInfo(TypeIds.T_JavaLangInteger, ConstantPool.JavaLangIntegerConstantPoolName);
break;
case TypeIds.T_long :
info = new VerificationTypeInfo(TypeIds.T_JavaLangLong, ConstantPool.JavaLangLongConstantPoolName);
break;
case TypeIds.T_float :
info = new VerificationTypeInfo(TypeIds.T_JavaLangFloat, ConstantPool.JavaLangFloatConstantPoolName);
break;
case TypeIds.T_double :
info = new VerificationTypeInfo(TypeIds.T_JavaLangDouble, ConstantPool.JavaLangDoubleConstantPoolName);
break;
case TypeIds.T_boolean :
info = new VerificationTypeInfo(TypeIds.T_JavaLangBoolean, ConstantPool.JavaLangBooleanConstantPoolName);
}
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (info != null && (numberOfStackItems >= 1)) {
this.currentFrame.stackItems[numberOfStackItems - 1] = info;
}
}
public void checkcast(TypeBinding typeBinding) {
super.checkcast(typeBinding);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(typeBinding);
}
}
public void d2f() {
super.d2f();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
}
}
public void d2i() {
super.d2i();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
public void d2l() {
super.d2l();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
}
}
public void dadd() {
super.dadd();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void daload() {
super.daload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void dastore() {
super.dastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=3;
}
}
public void dcmpg() {
super.dcmpg();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
this.currentFrame.addStackItem(TypeBinding.INT);
}
}
public void dcmpl() {
super.dcmpl();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
this.currentFrame.addStackItem(TypeBinding.INT);
}
}
public void dconst_0() {
super.dconst_0();
this.currentFrame.addStackItem(TypeBinding.DOUBLE);
}
public void dconst_1() {
super.dconst_1();
this.currentFrame.addStackItem(TypeBinding.DOUBLE);
}
public void ddiv() {
super.ddiv();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void decrStackSize(int offset) {
super.decrStackSize(offset);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems --;
}
}
public void dload(int iArg) {
super.dload(iArg);
this.currentFrame.addStackItem(getLocal(iArg, this.currentFrame));
}
public void dload_0() {
super.dload_0();
this.currentFrame.addStackItem(getLocal(0, this.currentFrame));
}
public void dload_1() {
super.dload_1();
this.currentFrame.addStackItem(getLocal(1, this.currentFrame));
}
public void dload_2() {
super.dload_2();
this.currentFrame.addStackItem(getLocal(2, this.currentFrame));
}
public void dload_3() {
super.dload_3();
this.currentFrame.addStackItem(getLocal(3, this.currentFrame));
}
public void dmul() {
super.dmul();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void drem() {
super.drem();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void dreturn() {
super.dreturn();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
this.framePositions.add(new Integer(this.position));
}
public void dstore(int iArg) {
super.dstore(iArg);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(iArg, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void dstore_0() {
super.dstore_0();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(0, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void dstore_1() {
super.dstore_1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(1, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void dstore_2() {
super.dstore_2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(2, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void dstore_3() {
super.dstore_3();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(3, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void dsub() {
super.dsub();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void dup() {
super.dup();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.addStackItem(this.currentFrame.stackItems[numberOfStackItems - 1]);
}
}
public void dup_x1() {
super.dup_x1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 2) {
VerificationTypeInfo info = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
VerificationTypeInfo info2 = this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
}
}
public void dup_x2() {
super.dup_x2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 2) {
VerificationTypeInfo info = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
VerificationTypeInfo info2 = this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
switch(info2.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
break;
default:
numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info3 = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info3);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
}
}
}
}
public void dup2() {
super.dup2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
switch(info.id()) {
case TypeIds.T_double :
case TypeIds.T_long :
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info);
break;
default:
numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info2 = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
}
}
}
}
public void dup2_x1() {
super.dup2_x1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 2) {
VerificationTypeInfo info = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
VerificationTypeInfo info2 = this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
switch(info.id()) {
case TypeIds.T_double :
case TypeIds.T_long :
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
break;
default:
numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info3 = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info3);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
}
}
}
}
public void dup2_x2() {
super.dup2_x2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 2) {
VerificationTypeInfo info = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
VerificationTypeInfo info2 = this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
switch(info.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
switch(info2.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
// form 4
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
break;
default:
// form 2
numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info3 = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info3);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
}
}
break;
default:
numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info3 = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
switch(info3.id()) {
case TypeIds.T_long :
case TypeIds.T_double :
// form 3
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info3);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
break;
default:
// form 1
numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
VerificationTypeInfo info4 = this.currentFrame.stackItems[numberOfStackItems - 1];
this.currentFrame.numberOfStackItems--;
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
this.currentFrame.addStackItem(info4);
this.currentFrame.addStackItem(info3);
this.currentFrame.addStackItem(info2);
this.currentFrame.addStackItem(info);
}
}
}
}
}
}
public void exitUserScope(BlockScope currentScope) {
int index = this.visibleLocalsCount - 1;
while (index >= 0) {
LocalVariableBinding visibleLocal = visibleLocals[index];
if (visibleLocal == null) {
index--;
continue;
}
if (visibleLocal.declaringScope != currentScope) // left currentScope
break;
// there may be some preserved locals never initialized
if (visibleLocal.initializationCount > 0){
this.currentFrame.removeLocals(visibleLocal.resolvedPosition);
}
index--;
}
if (currentScope != null) {
int localIndex = currentScope.localIndex;
if (localIndex != 0) {
for (int i = 0; i < localIndex; i++) {
LocalVariableBinding variableBinding = currentScope.locals[i];
if (variableBinding != null && variableBinding.useFlag == LocalVariableBinding.USED && variableBinding.resolvedPosition != -1) {
this.currentFrame.removeLocals(variableBinding.resolvedPosition);
}
}
}
}
super.exitUserScope(currentScope);
}
public void exitUserScope(BlockScope currentScope, LocalVariableBinding binding) {
int index = this.visibleLocalsCount - 1;
while (index >= 0) {
LocalVariableBinding visibleLocal = visibleLocals[index];
if (visibleLocal == null || visibleLocal == binding) {
index--;
continue;
}
if (visibleLocal.declaringScope != currentScope) // left currentScope
break;
// there may be some preserved locals never initialized
if (visibleLocal.initializationCount > 0){
this.currentFrame.removeLocals(visibleLocal.resolvedPosition);
}
index--;
}
if (currentScope != null) {
int localIndex = currentScope.localIndex;
if (localIndex != 0) {
for (int i = 0; i < localIndex; i++) {
LocalVariableBinding variableBinding = currentScope.locals[i];
if (variableBinding != null && variableBinding != binding && variableBinding.useFlag == LocalVariableBinding.USED && variableBinding.resolvedPosition != -1) {
this.currentFrame.removeLocals(variableBinding.resolvedPosition);
}
}
}
}
this.storeStackMapFrame();
super.exitUserScope(currentScope, binding);
}
public void f2d() {
super.f2d();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
}
}
public void f2i() {
super.f2i();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
public void f2l() {
super.f2l();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
}
}
public void fadd() {
super.fadd();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void faload() {
super.faload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void fastore() {
super.fastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=3;
}
}
public void fcmpg() {
super.fcmpg();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
this.currentFrame.addStackItem(TypeBinding.INT);
}
}
public void fcmpl() {
super.fcmpl();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
this.currentFrame.addStackItem(TypeBinding.INT);
}
}
public void fconst_0() {
super.fconst_0();
this.currentFrame.addStackItem(TypeBinding.FLOAT);
}
public void fconst_1() {
super.fconst_1();
this.currentFrame.addStackItem(TypeBinding.FLOAT);
}
public void fconst_2() {
super.fconst_2();
this.currentFrame.addStackItem(TypeBinding.FLOAT);
}
public void fdiv() {
super.fdiv();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void fload(int iArg) {
super.fload(iArg);
this.currentFrame.addStackItem(getLocal(iArg, this.currentFrame));
}
public void fload_0() {
super.fload_0();
this.currentFrame.addStackItem(getLocal(0, this.currentFrame));
}
public void fload_1() {
super.fload_1();
this.currentFrame.addStackItem(getLocal(1, this.currentFrame));
}
public void fload_2() {
super.fload_2();
this.currentFrame.addStackItem(getLocal(2, this.currentFrame));
}
public void fload_3() {
super.fload_3();
this.currentFrame.addStackItem(getLocal(3, this.currentFrame));
}
public void fmul() {
super.fmul();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void frem() {
super.frem();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void freturn() {
super.freturn();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
this.framePositions.add(new Integer(this.position));
}
public void fstore(int iArg) {
super.fstore(iArg);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(iArg, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void fstore_0() {
super.fstore_0();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(0, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void fstore_1() {
super.fstore_1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(1, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void fstore_2() {
super.fstore_2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(2, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void fstore_3() {
super.fstore_3();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(3, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void fsub() {
super.fsub();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void generateBoxingConversion(int unboxedTypeID) {
super.generateBoxingConversion(unboxedTypeID);
VerificationTypeInfo info = null;
switch (unboxedTypeID) {
case TypeIds.T_byte :
info = new VerificationTypeInfo(TypeIds.T_JavaLangByte, ConstantPool.JavaLangByteConstantPoolName);
break;
case TypeIds.T_short :
info = new VerificationTypeInfo(TypeIds.T_JavaLangShort, ConstantPool.JavaLangShortConstantPoolName);
break;
case TypeIds.T_char :
info = new VerificationTypeInfo(TypeIds.T_JavaLangCharacter, ConstantPool.JavaLangCharacterConstantPoolName);
break;
case TypeIds.T_int :
info = new VerificationTypeInfo(TypeIds.T_JavaLangInteger, ConstantPool.JavaLangIntegerConstantPoolName);
break;
case TypeIds.T_long :
info = new VerificationTypeInfo(TypeIds.T_JavaLangLong, ConstantPool.JavaLangLongConstantPoolName);
break;
case TypeIds.T_float :
info = new VerificationTypeInfo(TypeIds.T_JavaLangFloat, ConstantPool.JavaLangFloatConstantPoolName);
break;
case TypeIds.T_double :
info = new VerificationTypeInfo(TypeIds.T_JavaLangDouble, ConstantPool.JavaLangDoubleConstantPoolName);
break;
case TypeIds.T_boolean :
info = new VerificationTypeInfo(TypeIds.T_JavaLangBoolean, ConstantPool.JavaLangBooleanConstantPoolName);
}
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (info != null && (numberOfStackItems >= 1)) {
this.currentFrame.stackItems[numberOfStackItems - 1] = info;
}
}
public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite, Binding target, Scope scope) {
if (mappingSequence == null) {
if (target instanceof LocalVariableBinding) {
scope.problemReporter().needImplementation(); //TODO (philippe) should improve local emulation failure reporting
} else {
scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
this.currentFrame.addStackItem((ReferenceBinding)target);
}
return;
}
if (mappingSequence == BlockScope.NoEnclosingInstanceInConstructorCall) {
scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, true);
this.currentFrame.addStackItem((ReferenceBinding)target);
return;
} else if (mappingSequence == BlockScope.NoEnclosingInstanceInStaticContext) {
scope.problemReporter().noSuchEnclosingInstance((ReferenceBinding)target, invocationSite, false);
this.currentFrame.addStackItem((ReferenceBinding)target);
return;
}
if (mappingSequence == BlockScope.EmulationPathToImplicitThis) {
this.aload_0();
return;
} else if (mappingSequence[0] instanceof FieldBinding) {
FieldBinding fieldBinding = (FieldBinding) mappingSequence[0];
this.aload_0();
this.getfield(fieldBinding);
} else {
load((LocalVariableBinding) mappingSequence[0]);
}
for (int i = 1, length = mappingSequence.length; i < length; i++) {
if (mappingSequence[i] instanceof FieldBinding) {
FieldBinding fieldBinding = (FieldBinding) mappingSequence[i];
this.getfield(fieldBinding);
} else {
this.invokestatic((MethodBinding) mappingSequence[i]);
}
}
}
public void generateUnboxingConversion(int unboxedTypeID) {
super.generateUnboxingConversion(unboxedTypeID);
VerificationTypeInfo info = null;
switch (unboxedTypeID) {
case TypeIds.T_byte :
info = new VerificationTypeInfo(TypeBinding.BYTE);
break;
case TypeIds.T_short :
info = new VerificationTypeInfo(TypeBinding.SHORT);
break;
case TypeIds.T_char :
info = new VerificationTypeInfo(TypeBinding.CHAR);
break;
case TypeIds.T_int :
info = new VerificationTypeInfo(TypeBinding.INT);
break;
case TypeIds.T_long :
info = new VerificationTypeInfo(TypeBinding.LONG);
break;
case TypeIds.T_float :
info = new VerificationTypeInfo(TypeBinding.FLOAT);
break;
case TypeIds.T_double :
info = new VerificationTypeInfo(TypeBinding.DOUBLE);
break;
case TypeIds.T_boolean :
info = new VerificationTypeInfo(TypeBinding.BOOLEAN);
}
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (info != null && (numberOfStackItems >= 1)) {
this.currentFrame.stackItems[numberOfStackItems - 1] = info;
}
}
public void getBaseTypeValue(int baseTypeID) {
super.getBaseTypeValue(baseTypeID);
VerificationTypeInfo info = null;
switch (baseTypeID) {
case TypeIds.T_byte :
info = new VerificationTypeInfo(TypeBinding.BYTE);
break;
case TypeIds.T_short :
info = new VerificationTypeInfo(TypeBinding.SHORT);
break;
case TypeIds.T_char :
info = new VerificationTypeInfo(TypeBinding.CHAR);
break;
case TypeIds.T_int :
info = new VerificationTypeInfo(TypeBinding.INT);
break;
case TypeIds.T_long :
info = new VerificationTypeInfo(TypeBinding.LONG);
break;
case TypeIds.T_float :
info = new VerificationTypeInfo(TypeBinding.FLOAT);
break;
case TypeIds.T_double :
info = new VerificationTypeInfo(TypeBinding.DOUBLE);
break;
case TypeIds.T_boolean :
info = new VerificationTypeInfo(TypeBinding.BOOLEAN);
}
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (info != null && (numberOfStackItems >= 1)) {
this.currentFrame.stackItems[numberOfStackItems - 1] = info;
}
}
public void getfield(FieldBinding fieldBinding) {
super.getfield(fieldBinding);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(fieldBinding.type);
}
}
private VerificationTypeInfo getLocal(int resolvedPosition, StackMapFrame frame) {
VerificationTypeInfo verificationTypeInfo = frame.locals[resolvedPosition];
if (verificationTypeInfo == null) {
return null;
}
try {
if (verificationTypeInfo.tag == VerificationTypeInfo.ITEM_UNINITIALIZED_THIS
|| verificationTypeInfo.tag == VerificationTypeInfo.ITEM_UNINITIALIZED) {
return verificationTypeInfo;
}
return (VerificationTypeInfo) verificationTypeInfo.clone();
} catch (CloneNotSupportedException e) {
return verificationTypeInfo;
}
}
protected int getPosition() {
// need to record a new stack frame at this position
int pos = super.getPosition();
this.framePositions.add(new Integer(this.position));
storeStackMapFrame();
return pos;
}
public void getstatic(FieldBinding fieldBinding) {
super.getstatic(fieldBinding);
this.currentFrame.addStackItem(fieldBinding.type);
}
public void getTYPE(int baseTypeID) {
super.getTYPE(baseTypeID);
this.currentFrame.addStackItem(new VerificationTypeInfo(TypeIds.T_JavaLangClass, ConstantPool.JavaLangClassConstantPoolName));
}
/**
* We didn't call it goto, because there is a conflit with the goto keyword
*/
public void goto_(BranchLabel label) {
super.goto_(label);
this.framePositions.add(new Integer(this.position));
}
public void goto_w(BranchLabel label) {
super.goto_w(label);
this.framePositions.add(new Integer(this.position));
}
public void i2b() {
super.i2b();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BYTE);
}
}
public void i2c() {
super.i2c();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.CHAR);
}
}
public void i2d() {
super.i2d();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
}
}
public void i2f() {
super.i2f();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
}
}
public void i2l() {
super.i2l();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.LONG);
}
}
public void i2s() {
super.i2s();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.SHORT);
}
}
public void iadd() {
super.iadd();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void iaload() {
super.iaload();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void iand() {
super.iand();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void iastore() {
super.iastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=3;
}
}
public void iconst_0() {
super.iconst_0();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void iconst_1() {
super.iconst_1();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void iconst_2() {
super.iconst_2();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void iconst_3() {
super.iconst_3();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void iconst_4() {
super.iconst_4();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void iconst_5() {
super.iconst_5();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void iconst_m1() {
super.iconst_m1();
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void idiv() {
super.idiv();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void if_acmpeq(BranchLabel lbl) {
super.if_acmpeq(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_acmpne(BranchLabel lbl) {
super.if_acmpne(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_icmpeq(BranchLabel lbl) {
super.if_icmpeq(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_icmpge(BranchLabel lbl) {
super.if_icmpge(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_icmpgt(BranchLabel lbl) {
super.if_icmpgt(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_icmple(BranchLabel lbl) {
super.if_icmple(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_icmplt(BranchLabel lbl) {
super.if_icmplt(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void if_icmpne(BranchLabel lbl) {
super.if_icmpne(lbl);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
public void ifeq(BranchLabel lbl) {
super.ifeq(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ifge(BranchLabel lbl) {
super.ifge(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ifgt(BranchLabel lbl) {
super.ifgt(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ifle(BranchLabel lbl) {
super.ifle(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void iflt(BranchLabel lbl) {
super.iflt(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ifne(BranchLabel lbl) {
super.ifne(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ifnonnull(BranchLabel lbl) {
super.ifnonnull(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ifnull(BranchLabel lbl) {
super.ifnull(lbl);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void iload(int iArg) {
super.iload(iArg);
this.currentFrame.addStackItem(getLocal(iArg, this.currentFrame));
}
public void iload_0() {
super.iload_0();
this.currentFrame.addStackItem(getLocal(0, this.currentFrame));
}
public void iload_1() {
super.iload_1();
this.currentFrame.addStackItem(getLocal(1, this.currentFrame));
}
public void iload_2() {
super.iload_2();
this.currentFrame.addStackItem(getLocal(2, this.currentFrame));
}
public void iload_3() {
super.iload_3();
this.currentFrame.addStackItem(getLocal(3, this.currentFrame));
}
public void imul() {
super.imul();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public boolean inlineForwardReferencesFromLabelsTargeting(BranchLabel targetLabel, int gotoLocation) {
if (targetLabel.delegate != null) return false; // already inlined
int chaining = L_UNKNOWN;
boolean removeFrame = true;
for (int i = this.countLabels - 1; i >= 0; i--) {
BranchLabel currentLabel = labels[i];
if (currentLabel.position != gotoLocation) break;
if (currentLabel == targetLabel) {
chaining |= L_CANNOT_OPTIMIZE;
continue;
}
if (currentLabel.isStandardLabel()) {
if (currentLabel.delegate != null) continue;
chaining |= L_OPTIMIZABLE;
if (currentLabel.forwardReferenceCount() == 0 && ((currentLabel.tagBits & BranchLabel.USED) != 0)) {
removeFrame = false;
}
continue;
}
// case label
removeFrame = false;
chaining |= L_CANNOT_OPTIMIZE;
}
if ((chaining & L_OPTIMIZABLE) != 0) {
for (int i = this.countLabels - 1; i >= 0; i--) {
BranchLabel currentLabel = labels[i];
if (currentLabel.position != gotoLocation) break;
if (currentLabel == targetLabel) continue;
if (currentLabel.isStandardLabel()) {
if (currentLabel.delegate != null) continue;
targetLabel.becomeDelegateFor(currentLabel);
// we should remove the frame corresponding to otherLabel position in order to prevent unused stack frame
if (removeFrame) {
currentLabel.tagBits &= ~BranchLabel.USED;
this.removeStackFrameFor(gotoLocation);
}
}
}
}
return (chaining & (L_OPTIMIZABLE|L_CANNOT_OPTIMIZE)) == L_OPTIMIZABLE; // check was some standards, and no case/recursive
}
public void init(ClassFile targetClassFile) {
super.init(targetClassFile);
this.frames = null;
this.currentFrame = null;
}
public void initializeMaxLocals(MethodBinding methodBinding) {
super.initializeMaxLocals(methodBinding);
StackMapFrame frame = new StackMapFrame();
frame.pc = -1;
if (this.maxLocals != 0) {
int resolvedPosition = 0;
// take into account enum constructor synthetic name+ordinal
final boolean isConstructor = methodBinding.isConstructor();
if (isConstructor) {
frame.putLocal(resolvedPosition, new VerificationTypeInfo(VerificationTypeInfo.ITEM_UNINITIALIZED_THIS, methodBinding.declaringClass));
resolvedPosition++;
} else if (!methodBinding.isStatic()) {
frame.putLocal(resolvedPosition, new VerificationTypeInfo(VerificationTypeInfo.ITEM_OBJECT, methodBinding.declaringClass));
resolvedPosition++;
}
if (isConstructor) {
if (methodBinding.declaringClass.isEnum()) {
frame.putLocal(resolvedPosition, new VerificationTypeInfo(TypeIds.T_JavaLangString, ConstantPool.JavaLangStringConstantPoolName));
resolvedPosition++;
frame.putLocal(resolvedPosition, new VerificationTypeInfo(TypeBinding.INT));
resolvedPosition++;
}
// take into account the synthetic parameters
if (methodBinding.declaringClass.isNestedType()) {
ReferenceBinding enclosingInstanceTypes[];
if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) {
for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) {
// an enclosingInstanceType can only be a reference binding. It cannot be
// LongBinding or DoubleBinding
frame.putLocal(resolvedPosition, new VerificationTypeInfo(enclosingInstanceTypes[i]));
resolvedPosition++;
}
}
TypeBinding[] arguments;
if ((arguments = methodBinding.parameters) != null) {
for (int i = 0, max = arguments.length; i < max; i++) {
final TypeBinding typeBinding = arguments[i];
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double :
case TypeIds.T_long :
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
SyntheticArgumentBinding syntheticArguments[];
if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) {
for (int i = 0, max = syntheticArguments.length; i < max; i++) {
final TypeBinding typeBinding = syntheticArguments[i].type;
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double :
case TypeIds.T_long :
resolvedPosition+=2;
break;
default:
resolvedPosition++;
}
}
}
} else {
TypeBinding[] arguments;
if ((arguments = methodBinding.parameters) != null) {
for (int i = 0, max = arguments.length; i < max; i++) {
final TypeBinding typeBinding = arguments[i];
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double :
case TypeIds.T_long :
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
}
} else {
TypeBinding[] arguments;
if ((arguments = methodBinding.parameters) != null) {
for (int i = 0, max = arguments.length; i < max; i++) {
final TypeBinding typeBinding = arguments[i];
frame.putLocal(resolvedPosition, new VerificationTypeInfo(typeBinding));
switch(typeBinding.id) {
case TypeIds.T_double :
case TypeIds.T_long :
resolvedPosition += 2;
break;
default:
resolvedPosition++;
}
}
}
}
}
try {
this.frames = new ArrayList();
this.frames.add(frame.clone());
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
this.currentFrame = frame;
this.framePositions = new HashSet();
this.variablesModificationsPositions = new ArrayList();
}
public void instance_of(TypeBinding typeBinding) {
super.instance_of(typeBinding);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
protected void invokeAccessibleObjectSetAccessible() {
super.invokeAccessibleObjectSetAccessible();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems-=2;
}
}
protected void invokeArrayNewInstance() {
super.invokeArrayNewInstance();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, ConstantPool.JavaLangObjectConstantPoolName);
}
}
public void invokeClassForName() {
super.invokeClassForName();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangClass, ConstantPool.JavaLangClassConstantPoolName);
}
}
protected void invokeClassGetDeclaredConstructor() {
super.invokeClassGetDeclaredConstructor();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangReflectConstructor, ConstantPool.JavaLangReflectConstructorConstantPoolName);
}
}
protected void invokeClassGetDeclaredField() {
super.invokeClassGetDeclaredField();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangReflectField, ConstantPool.JAVALANGREFLECTFIELD_CONSTANTPOOLNAME);
}
}
protected void invokeClassGetDeclaredMethod() {
super.invokeClassGetDeclaredMethod();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems-=2;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangReflectMethod, ConstantPool.JAVALANGREFLECTMETHOD_CONSTANTPOOLNAME);
}
}
public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) {
super.invokeEnumOrdinal(enumTypeConstantPoolName);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
public void invokeinterface(MethodBinding methodBinding) {
super.invokeinterface(methodBinding);
int argCount = 1;
argCount += methodBinding.parameters.length;
if (this.currentFrame.numberOfStackItems >= argCount) {
this.currentFrame.numberOfStackItems -= argCount;
}
if (methodBinding.returnType != TypeBinding.VOID) {
this.currentFrame.addStackItem(methodBinding.returnType);
}
}
public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) {
// invokespecial: java.lang.AssertionError.<init>(typeBindingID)V
super.invokeJavaLangAssertionErrorConstructor(typeBindingID);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
}
public void invokeJavaLangAssertionErrorDefaultConstructor() {
super.invokeJavaLangAssertionErrorDefaultConstructor();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
}
public void invokeJavaLangClassDesiredAssertionStatus() {
// invokevirtual: java.lang.Class.desiredAssertionStatus()Z;
super.invokeJavaLangClassDesiredAssertionStatus();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BOOLEAN);
}
}
public void invokeJavaLangEnumvalueOf(ReferenceBinding binding) {
// invokestatic: java.lang.Enum.valueOf(Class,String)
super.invokeJavaLangEnumvalueOf(binding);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems -= 2;
this.currentFrame.addStackItem(binding);
}
}
public void invokeJavaLangEnumValues(TypeBinding enumBinding, ArrayBinding arrayBinding) {
super.invokeJavaLangEnumValues(enumBinding, arrayBinding);
this.currentFrame.addStackItem(arrayBinding);
}
public void invokeJavaLangErrorConstructor() {
super.invokeJavaLangErrorConstructor();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems --;
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
}
public void invokeJavaLangReflectConstructorNewInstance() {
super.invokeJavaLangReflectConstructorNewInstance();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, ConstantPool.JavaLangObjectConstantPoolName);
}
}
protected void invokeJavaLangReflectFieldGetter(int typeID) {
super.invokeJavaLangReflectFieldGetter(typeID);
VerificationTypeInfo info = null;
switch (typeID) {
case TypeIds.T_int :
info = new VerificationTypeInfo(TypeBinding.INT);
break;
case TypeIds.T_byte :
info = new VerificationTypeInfo(TypeBinding.BYTE);
break;
case TypeIds.T_short :
info = new VerificationTypeInfo(TypeBinding.SHORT);
break;
case TypeIds.T_long :
info = new VerificationTypeInfo(TypeBinding.LONG);
break;
case TypeIds.T_float :
info = new VerificationTypeInfo(TypeBinding.FLOAT);
break;
case TypeIds.T_double :
info = new VerificationTypeInfo(TypeBinding.DOUBLE);
break;
case TypeIds.T_char :
info = new VerificationTypeInfo(TypeBinding.CHAR);
break;
case TypeIds.T_boolean :
info = new VerificationTypeInfo(TypeBinding.BOOLEAN);
break;
default :
info = new VerificationTypeInfo(TypeIds.T_JavaLangObject, ConstantPool.JavaLangObjectConstantPoolName);
break;
}
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = info;
}
}
protected void invokeJavaLangReflectFieldSetter(int typeID) {
super.invokeJavaLangReflectFieldSetter(typeID);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems -= 2;
}
}
public void invokeJavaLangReflectMethodInvoke() {
super.invokeJavaLangReflectMethodInvoke();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems -= 3;
}
}
public void invokeJavaUtilIteratorHasNext() {
super.invokeJavaUtilIteratorHasNext();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.BOOLEAN);
}
}
public void invokeJavaUtilIteratorNext() {
// invokeinterface java.util.Iterator.next()java.lang.Object
super.invokeJavaUtilIteratorNext();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, ConstantPool.JavaLangObjectConstantPoolName);
}
}
public void invokeNoClassDefFoundErrorStringConstructor() {
super.invokeNoClassDefFoundErrorStringConstructor();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems --;
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
}
public void invokeObjectGetClass() {
super.invokeObjectGetClass();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangClass, ConstantPool.JavaLangClassConstantPoolName);
}
}
public void invokespecial(MethodBinding methodBinding) {
super.invokespecial(methodBinding);
// initialize to 0 since we will manually remove 'this'
int argCount = 0;
if (methodBinding.isConstructor()) {
final ReferenceBinding declaringClass = methodBinding.declaringClass;
if (declaringClass.isNestedType()) {
// enclosing instances
TypeBinding[] syntheticArgumentTypes = declaringClass.syntheticEnclosingInstanceTypes();
if (syntheticArgumentTypes != null) {
argCount += syntheticArgumentTypes.length;
}
// outer local variables
SyntheticArgumentBinding[] syntheticArguments = declaringClass.syntheticOuterLocalVariables();
if (syntheticArguments != null) {
argCount += syntheticArguments.length;
}
}
if (declaringClass.isEnum()) {
argCount += 2;
}
argCount += methodBinding.parameters.length;
if (this.currentFrame.numberOfStackItems >= (argCount + 1)) {
this.currentFrame.numberOfStackItems -= argCount;
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
} else {
argCount = 1;
argCount += methodBinding.parameters.length;
if (this.currentFrame.numberOfStackItems >= argCount) {
this.currentFrame.numberOfStackItems -= argCount;
}
if (methodBinding.returnType != TypeBinding.VOID) {
this.currentFrame.addStackItem(methodBinding.returnType);
}
}
}
public void invokestatic(MethodBinding methodBinding) {
super.invokestatic(methodBinding);
int parametersLength = methodBinding.parameters.length;
if (this.currentFrame.numberOfStackItems >= parametersLength) {
this.currentFrame.numberOfStackItems -= parametersLength;
}
if (methodBinding.returnType != TypeBinding.VOID) {
this.currentFrame.addStackItem(methodBinding.returnType);
}
}
public void invokeStringConcatenationAppendForType(int typeID) {
super.invokeStringConcatenationAppendForType(typeID);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void invokeStringConcatenationDefaultConstructor() {
// invokespecial: java.lang.StringBuffer.<init>()V
super.invokeStringConcatenationDefaultConstructor();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
}
public void invokeStringConcatenationStringConstructor() {
super.invokeStringConcatenationStringConstructor();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--; // remove argument
this.currentFrame.initializeReceiver();
this.currentFrame.numberOfStackItems--; // remove the top of stack
}
}
public void invokeStringConcatenationToString() {
super.invokeStringConcatenationToString();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangString, ConstantPool.JavaLangStringConstantPoolName);
}
}
public void invokeStringValueOf(int typeID) {
super.invokeStringValueOf(typeID);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangString, ConstantPool.JavaLangStringConstantPoolName);
}
}
public void invokeSystemArraycopy() {
super.invokeSystemArraycopy();
if (this.currentFrame.numberOfStackItems >= 5) {
this.currentFrame.numberOfStackItems -= 5;
}
}
public void invokeThrowableGetMessage() {
super.invokeThrowableGetMessage();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangString, ConstantPool.JavaLangStringConstantPoolName);
}
}
public void invokevirtual(MethodBinding methodBinding) {
super.invokevirtual(methodBinding);
int argCount = 1;
argCount += methodBinding.parameters.length;
if (this.currentFrame.numberOfStackItems >= argCount) {
this.currentFrame.numberOfStackItems -= argCount;
}
if (methodBinding.returnType != TypeBinding.VOID) {
this.currentFrame.addStackItem(methodBinding.returnType);
}
}
public void ior() {
super.ior();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void irem() {
super.irem();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ireturn() {
super.ireturn();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
this.framePositions.add(new Integer(this.position));
}
public void ishl() {
super.ishl();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ishr() {
super.ishr();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void istore(int iArg) {
super.istore(iArg);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(iArg, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void istore_0() {
super.istore_0();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(0, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void istore_1() {
super.istore_1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(1, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void istore_2() {
super.istore_2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(2, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void istore_3() {
super.istore_3();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(3, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void isub() {
super.isub();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void iushr() {
super.iushr();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void ixor() {
super.ixor();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void l2d() {
super.l2d();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.DOUBLE);
}
}
public void l2f() {
super.l2f();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.FLOAT);
}
}
public void l2i() {
super.l2i();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
public void ladd() {
super.ladd();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void laload() {
super.laload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void land() {
super.land();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lastore() {
super.lastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems -= 3;
}
}
public void lcmp() {
super.lcmp();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.stackItems[this.currentFrame.numberOfStackItems - 1] = new VerificationTypeInfo(TypeBinding.INT);
}
}
public void lconst_0() {
super.lconst_0();
this.currentFrame.addStackItem(TypeBinding.LONG);
}
public void lconst_1() {
super.lconst_1();
this.currentFrame.addStackItem(TypeBinding.LONG);
}
public void ldc(float constant) {
super.ldc(constant);
this.currentFrame.addStackItem(TypeBinding.FLOAT);
}
public void ldc(int constant) {
super.ldc(constant);
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void ldc(TypeBinding typeBinding) {
super.ldc(typeBinding);
this.currentFrame.addStackItem(typeBinding);
}
public void ldc2_w(double constant) {
super.ldc2_w(constant);
this.currentFrame.addStackItem(TypeBinding.DOUBLE);
}
public void ldc2_w(long constant) {
super.ldc2_w(constant);
this.currentFrame.addStackItem(TypeBinding.LONG);
}
public void ldcForIndex(int index, char[] constant) {
super.ldcForIndex(index, constant);
this.currentFrame.addStackItem(new VerificationTypeInfo(TypeIds.T_JavaLangString, ConstantPool.JavaLangStringConstantPoolName));
}
public void ldiv() {
super.ldiv();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lload(int iArg) {
super.lload(iArg);
this.currentFrame.addStackItem(getLocal(iArg, this.currentFrame));
}
public void lload_0() {
super.lload_0();
this.currentFrame.addStackItem(getLocal(0, this.currentFrame));
}
public void lload_1() {
super.lload_1();
this.currentFrame.addStackItem(getLocal(1, this.currentFrame));
}
public void lload_2() {
super.lload_2();
this.currentFrame.addStackItem(getLocal(2, this.currentFrame));
}
public void lload_3() {
super.lload_3();
this.currentFrame.addStackItem(getLocal(3, this.currentFrame));
}
public void lmul() {
super.lmul();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lookupswitch(CaseLabel defaultLabel, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
super.lookupswitch(defaultLabel, keys, sortedIndexes, casesLabel);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lor() {
super.lor();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lrem() {
super.lrem();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lreturn() {
super.lreturn();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
this.framePositions.add(new Integer(this.position));
}
public void lshl() {
super.lshl();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lshr() {
super.lshr();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lstore(int iArg) {
super.lstore(iArg);
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(iArg, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void lstore_0() {
super.lstore_0();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(0, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void lstore_1() {
super.lstore_1();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(1, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void lstore_2() {
super.lstore_2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(2, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void lstore_3() {
super.lstore_3();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.putLocal(3, this.currentFrame.stackItems[numberOfStackItems - 1]);
this.currentFrame.numberOfStackItems--;
}
}
public void lsub() {
super.lsub();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lushr() {
super.lushr();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void lxor() {
super.lxor();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void monitorenter() {
super.monitorenter();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void monitorexit() {
super.monitorexit();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void multianewarray(TypeBinding typeBinding, int dimensions) {
super.multianewarray(typeBinding, dimensions);
if (this.currentFrame.numberOfStackItems >= dimensions) {
this.currentFrame.numberOfStackItems -= dimensions;
}
char[] brackets = new char[dimensions];
for (int i = dimensions - 1; i >= 0; i--) brackets[i] = '[';
char[] constantPoolName = CharOperation.concat(brackets, typeBinding.constantPoolName());
this.currentFrame.addStackItem(new VerificationTypeInfo(typeBinding.id, constantPoolName));
}
// We didn't call it new, because there is a conflit with the new keyword
public void new_(TypeBinding typeBinding) {
int pc = this.position;
super.new_(typeBinding);
final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(VerificationTypeInfo.ITEM_UNINITIALIZED, typeBinding);
verificationTypeInfo.offset = pc;
this.currentFrame.addStackItem(verificationTypeInfo);
}
public void newarray(int array_Type) {
super.newarray(array_Type);
char[] constantPoolName = null;
switch (array_Type) {
case ClassFileConstants.INT_ARRAY :
constantPoolName = new char[] { '[', 'I' };
break;
case ClassFileConstants.BYTE_ARRAY :
constantPoolName = new char[] { '[', 'B' };
break;
case ClassFileConstants.BOOLEAN_ARRAY :
constantPoolName = new char[] { '[', 'Z' };
break;
case ClassFileConstants.SHORT_ARRAY :
constantPoolName = new char[] { '[', 'S' };
break;
case ClassFileConstants.CHAR_ARRAY :
constantPoolName = new char[] { '[', 'C' };
break;
case ClassFileConstants.LONG_ARRAY :
constantPoolName = new char[] { '[', 'J' };
break;
case ClassFileConstants.FLOAT_ARRAY :
constantPoolName = new char[] { '[', 'F' };
break;
case ClassFileConstants.DOUBLE_ARRAY :
constantPoolName = new char[] { '[', 'D' };
break;
}
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
this.currentFrame.stackItems[numberOfStackItems - 1] = new VerificationTypeInfo(TypeIds.T_JavaLangObject, constantPoolName);
}
}
public void newJavaLangAssertionError() {
int pc = this.position;
super.newJavaLangAssertionError();
final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangAssertionError, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangAssertionErrorConstantPoolName);
verificationTypeInfo.offset = pc;
this.currentFrame.addStackItem(verificationTypeInfo);
}
public void newJavaLangError() {
int pc = this.position;
super.newJavaLangError();
final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangError, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangErrorConstantPoolName);
verificationTypeInfo.offset = pc;
this.currentFrame.addStackItem(verificationTypeInfo);
}
public void newNoClassDefFoundError() {
int pc = this.position;
super.newNoClassDefFoundError();
final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangNoClassDefError, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName);
verificationTypeInfo.offset = pc;
this.currentFrame.addStackItem(verificationTypeInfo);
}
public void newStringContatenation() {
int pc = this.position;
super.newStringContatenation();
// in 1.6, string concatenation uses StringBuilder
final VerificationTypeInfo verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangStringBuilder, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangStringBuilderConstantPoolName);
verificationTypeInfo.offset = pc;
this.currentFrame.addStackItem(verificationTypeInfo);
}
public void newWrapperFor(int typeID) {
int pc = this.position;
super.newWrapperFor(typeID);
VerificationTypeInfo verificationTypeInfo = null;
switch (typeID) {
case TypeIds.T_int : // new: java.lang.Integer
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangInteger, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangIntegerConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_boolean : // new: java.lang.Boolean
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangBoolean, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangBooleanConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_byte : // new: java.lang.Byte
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangByte, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangByteConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_char : // new: java.lang.Character
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangCharacter, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangCharacterConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_float : // new: java.lang.Float
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangFloat, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangFloatConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_double : // new: java.lang.Double
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangDouble, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangDoubleConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_short : // new: java.lang.Short
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangShort, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangShortConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_long : // new: java.lang.Long
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangLong, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangLongConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
break;
case TypeIds.T_void : // new: java.lang.Void
verificationTypeInfo = new VerificationTypeInfo(TypeIds.T_JavaLangVoid, VerificationTypeInfo.ITEM_UNINITIALIZED, ConstantPool.JavaLangVoidConstantPoolName);
this.currentFrame.addStackItem(verificationTypeInfo);
}
if (verificationTypeInfo != null) {
verificationTypeInfo.offset = pc;
}
}
public void optimizeBranch(int oldPosition, BranchLabel lbl) {
super.optimizeBranch(oldPosition, lbl);
int frameIndex = this.frames.size() - 1;
loop: while(frameIndex > 0) {
StackMapFrame frame = (StackMapFrame) this.frames.get(frameIndex);
if (frame.pc == oldPosition) {
if (this.framePositions.remove(new Integer(oldPosition))) {
this.framePositions.add(new Integer(this.position));
}
if (this.variablesModificationsPositions.remove(new Integer(oldPosition))) {
this.variablesModificationsPositions.add(new Integer(this.position));
}
frame.pc = this.position;
StackMapFrame previousFrame = (StackMapFrame) this.frames.get(frameIndex - 1);
if (previousFrame.pc == this.position) {
// remove the current frame
this.frames.set(frameIndex - 1, frame);
this.frames.remove(frameIndex);
}
break loop;
} else if (frame.pc > oldPosition) {
return;
}
frameIndex--;
}
}
public void pop() {
super.pop();
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void pop2() {
super.pop2();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 1) {
switch(this.currentFrame.stackItems[numberOfStackItems - 1].id()) {
case TypeIds.T_long :
case TypeIds.T_double :
this.currentFrame.numberOfStackItems--;
break;
default:
if (numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems -= 2;
}
}
}
}
public void popStateIndex() {
this.stateIndexesCounter--;
}
public void pushOnStack(TypeBinding binding) {
super.pushOnStack(binding);
this.currentFrame.addStackItem(binding);
}
public void putfield(FieldBinding fieldBinding) {
super.putfield(fieldBinding);
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems -= 2;
}
}
public void pushStateIndex(int naturalExitMergeInitStateIndex) {
if (this.stateIndexes == null) {
this.stateIndexes = new int[3];
}
int length = this.stateIndexes.length;
if (length == this.stateIndexesCounter) {
// resize
System.arraycopy(this.stateIndexes, 0, (this.stateIndexes = new int[length * 2]), 0, length);
}
this.stateIndexes[this.stateIndexesCounter++] = naturalExitMergeInitStateIndex;
}
public void putstatic(FieldBinding fieldBinding) {
super.putstatic(fieldBinding);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void recordExpressionType(TypeBinding typeBinding) {
super.recordExpressionType(typeBinding);
this.currentFrame.setTopOfStack(typeBinding);
}
public void removeVariable(LocalVariableBinding localBinding) {
this.currentFrame.removeLocals(localBinding.resolvedPosition);
super.removeVariable(localBinding);
}
public void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) {
int index = this.visibleLocalsCount;
loop : for (int i = 0; i < index; i++) {
LocalVariableBinding localBinding = visibleLocals[i];
if (localBinding != null && localBinding.initializationCount > 0) {
boolean isDefinitelyAssigned = isDefinitelyAssigned(scope, initStateIndex, localBinding);
if (!isDefinitelyAssigned) {
if (this.stateIndexes != null) {
for (int j = 0, max = this.stateIndexesCounter; j < max; j++) {
if (isDefinitelyAssigned(scope, this.stateIndexes[j], localBinding)) {
continue loop;
}
}
}
this.currentFrame.removeLocals(localBinding.resolvedPosition);
localBinding.recordInitializationEndPC(position);
}
}
}
Integer newValue = new Integer(this.position);
if (this.variablesModificationsPositions.size() == 0 || !this.variablesModificationsPositions.get(this.variablesModificationsPositions.size() - 1).equals(newValue)) {
this.variablesModificationsPositions.add(newValue);
}
storeStackMapFrame();
}
public void storeStackMapFrame() {
int frameSize = this.frames.size();
StackMapFrame mapFrame = null;
try {
mapFrame = (StackMapFrame) this.currentFrame.clone();
mapFrame.pc = this.position;
} catch(CloneNotSupportedException e) {
// ignore
}
if (frameSize == 0) {
this.frames.add(mapFrame);
} else {
StackMapFrame lastFrame = (StackMapFrame) this.frames.get(frameSize - 1);
if (lastFrame.pc == this.position) {
this.frames.set(frameSize - 1, mapFrame);
} else {
this.frames.add(mapFrame);
}
}
}
public void return_() {
super.return_();
this.framePositions.add(new Integer(this.position));
}
public void saload() {
super.saload();
if (this.currentFrame.numberOfStackItems >= 2) {
this.currentFrame.numberOfStackItems--;
this.currentFrame.replaceWithElementType();
}
}
public void sastore() {
super.sastore();
if (this.currentFrame.numberOfStackItems >= 3) {
this.currentFrame.numberOfStackItems -= 3;
}
}
public void sipush(int s) {
super.sipush(s);
this.currentFrame.addStackItem(TypeBinding.INT);
}
public void store(LocalVariableBinding localBinding, boolean valueRequired) {
super.store(localBinding, valueRequired);
final TypeBinding typeBinding = localBinding.type;
switch(typeBinding.id) {
default:
// Reference object
this.currentFrame.locals[localBinding.resolvedPosition] = new VerificationTypeInfo(typeBinding);
}
}
public void swap() {
super.swap();
int numberOfStackItems = this.currentFrame.numberOfStackItems;
if (numberOfStackItems >= 2) {
try {
VerificationTypeInfo info = (VerificationTypeInfo) this.currentFrame.stackItems[numberOfStackItems - 1].clone();
VerificationTypeInfo info2 = (VerificationTypeInfo) this.currentFrame.stackItems[numberOfStackItems - 2].clone();
this.currentFrame.stackItems[numberOfStackItems - 1] = info2;
this.currentFrame.stackItems[numberOfStackItems - 2] = info;
} catch (CloneNotSupportedException e) {
// ignore
}
}
}
public void tableswitch(CaseLabel defaultLabel, int low, int high, int[] keys, int[] sortedIndexes, CaseLabel[] casesLabel) {
super.tableswitch(defaultLabel, low, high, keys, sortedIndexes, casesLabel);
if (this.currentFrame.numberOfStackItems >= 1) {
this.currentFrame.numberOfStackItems--;
}
}
public void throwAnyException(LocalVariableBinding anyExceptionVariable) {
this.currentFrame.putLocal(anyExceptionVariable.resolvedPosition, new VerificationTypeInfo(VerificationTypeInfo.ITEM_OBJECT, anyExceptionVariable.type));
super.throwAnyException(anyExceptionVariable);
this.currentFrame.removeLocals(anyExceptionVariable.resolvedPosition);
}
public void removeStackFrameFor(int pos) {
// TODO (olivier) need to see how to get rid of some unnecessary frames
}
public void reset(ClassFile givenClassFile) {
super.reset(givenClassFile);
this.frames = null;
this.currentFrame = null;
this.framePositions = null;
this.variablesModificationsPositions = null;
}
protected void writePosition(BranchLabel label) {
super.writePosition(label);
framePositions.add(new Integer(label.position));
}
protected void writeWidePosition(BranchLabel label) {
super.writeWidePosition(label);
framePositions.add(new Integer(label.position));
}
protected void writePosition(BranchLabel label, int forwardReference) {
super.writePosition(label, forwardReference);
framePositions.add(new Integer(label.position));
}
}