X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;ds=sidebyside;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Fcodegen%2FCodeStream.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Fcodegen%2FCodeStream.java;h=343c4e60ee66b611d583a179be2571a45fc2d1a1;hb=c17753cd9e62cd1a71df3d88af908de0425ac33d;hp=4d7a6ef3388dfe237c1d777379dd0ce0905e3f91;hpb=040fa5af2cd00017cf3575950cdaade34a6d7f6c;p=org.ibex.tool.git diff --git a/src/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java b/src/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java index 4d7a6ef..343c4e6 100644 --- a/src/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java +++ b/src/org/eclipse/jdt/internal/compiler/codegen/CodeStream.java @@ -49,7 +49,9 @@ public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, Bas public AbstractMethodDeclaration methodDeclaration; public ExceptionLabel[] exceptionHandlers = new ExceptionLabel[LABELS_INCREMENT]; static ExceptionLabel[] noExceptionHandlers = new ExceptionLabel[LABELS_INCREMENT]; - public int exceptionHandlersNumber; + public int exceptionHandlersIndex; + public int exceptionHandlersCounter; + public static FieldBinding[] ImplicitThis = new FieldBinding[] {}; public boolean generateLineNumberAttributes; public boolean generateLocalVariableTableAttributes; @@ -65,11 +67,15 @@ public class CodeStream implements OperatorIds, ClassFileConstants, Opcodes, Bas public boolean wideMode = false; public static final CompilationResult RESTART_IN_WIDE_MODE = new CompilationResult((char[])null, 0, 0, 0); -public CodeStream(ClassFile classFile) { - generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0; - generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0; - if (generateLineNumberAttributes) { - lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions; + // target level to manage different code generation between different target levels + private long targetLevel; + +public CodeStream(ClassFile classFile, long targetLevel) { + this.targetLevel = targetLevel; + this.generateLineNumberAttributes = (classFile.produceDebugAttributes & CompilerOptions.Lines) != 0; + this.generateLocalVariableTableAttributes = (classFile.produceDebugAttributes & CompilerOptions.Vars) != 0; + if (this.generateLineNumberAttributes) { + this.lineSeparatorPositions = classFile.referenceBinding.scope.referenceCompilationUnit().compilationResult.lineSeparatorPositions; } } final public void aaload() { @@ -248,7 +254,7 @@ public final void anewarray(TypeBinding typeBinding) { } position++; bCodeStream[classFileOffset++] = OPC_anewarray; - writeUnsignedShort(constantPool.literalIndex(typeBinding)); + writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName())); } final public void areturn() { if (DEBUG) System.out.println(position + "\t\tareturn"); //$NON-NLS-1$ @@ -482,14 +488,14 @@ final public void castore() { bCodeStream[classFileOffset++] = OPC_castore; } public final void checkcast(TypeBinding typeBinding) { - if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding); //$NON-NLS-1$ + if (DEBUG) System.out.println(position + "\t\tcheckcast:"+typeBinding.debugName()); //$NON-NLS-1$ countLabels = 0; if (classFileOffset + 2 >= bCodeStream.length) { resizeByteArray(); } position++; bCodeStream[classFileOffset++] = OPC_checkcast; - writeUnsignedShort(constantPool.literalIndex(typeBinding)); + writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName())); } final public void d2f() { if (DEBUG) System.out.println(position + "\t\td2f"); //$NON-NLS-1$ @@ -1260,80 +1266,85 @@ public void generateClassLiteralAccessForType(TypeBinding accessedType, FieldBin this.getTYPE(accessedType.id); return; } - endLabel = new Label(this); - - if (syntheticFieldBinding != null) { // non interface case - this.getstatic(syntheticFieldBinding); - this.dup(); - this.ifnonnull(endLabel); - this.pop(); - } - - /* Macro for building a class descriptor object... using or not a field cache to store it into... - this sequence is responsible for building the actual class descriptor. - - If the fieldCache is set, then it is supposed to be the body of a synthetic access method - factoring the actual descriptor creation out of the invocation site (saving space). - If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since - we have no way to get a hand on the field cache to do better. */ - - // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError - - anyExceptionHandler = new ExceptionLabel(this, BaseTypes.NullBinding /* represents ClassNotFoundException*/); - this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$ - this.invokeClassForName(); - - /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565 - if (accessedType == BaseTypes.NullBinding) { - this.ldc("java.lang.Object"); //$NON-NLS-1$ - } else if (accessedType.isArrayType()) { - this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.')); + if (this.targetLevel >= ClassFileConstants.JDK1_5) { + // generation using the new ldc_w bytecode + this.ldc(accessedType); } else { - // we make it an array type (to avoid class initialization) - this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$ - } - this.invokeClassForName(); - if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class - this.invokeJavaLangClassGetComponentType(); - } - */ - /* We need to protect the runtime code from binary inconsistencies - in case the accessedType is missing, the ClassNotFoundException has to be converted - into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */ - anyExceptionHandler.placeEnd(); + endLabel = new Label(this); + if (syntheticFieldBinding != null) { // non interface case + this.getstatic(syntheticFieldBinding); + this.dup(); + this.ifnonnull(endLabel); + this.pop(); + } - if (syntheticFieldBinding != null) { // non interface case - this.dup(); - this.putstatic(syntheticFieldBinding); + /* Macro for building a class descriptor object... using or not a field cache to store it into... + this sequence is responsible for building the actual class descriptor. + + If the fieldCache is set, then it is supposed to be the body of a synthetic access method + factoring the actual descriptor creation out of the invocation site (saving space). + If the fieldCache is nil, then we are dumping the bytecode on the invocation site, since + we have no way to get a hand on the field cache to do better. */ + + + // Wrap the code in an exception handler to convert a ClassNotFoundException into a NoClassDefError + + anyExceptionHandler = new ExceptionLabel(this, BaseTypes.NullBinding /* represents ClassNotFoundException*/); + this.ldc(accessedType == BaseTypes.NullBinding ? "java.lang.Object" : String.valueOf(accessedType.constantPoolName()).replace('/', '.')); //$NON-NLS-1$ + this.invokeClassForName(); + + /* See https://bugs.eclipse.org/bugs/show_bug.cgi?id=37565 + if (accessedType == BaseTypes.NullBinding) { + this.ldc("java.lang.Object"); //$NON-NLS-1$ + } else if (accessedType.isArrayType()) { + this.ldc(String.valueOf(accessedType.constantPoolName()).replace('/', '.')); + } else { + // we make it an array type (to avoid class initialization) + this.ldc("[L" + String.valueOf(accessedType.constantPoolName()).replace('/', '.') + ";"); //$NON-NLS-1$//$NON-NLS-2$ + } + this.invokeClassForName(); + if (!accessedType.isArrayType()) { // extract the component type, which doesn't initialize the class + this.invokeJavaLangClassGetComponentType(); + } + */ + /* We need to protect the runtime code from binary inconsistencies + in case the accessedType is missing, the ClassNotFoundException has to be converted + into a NoClassDefError(old ex message), we thus need to build an exception handler for this one. */ + anyExceptionHandler.placeEnd(); + + if (syntheticFieldBinding != null) { // non interface case + this.dup(); + this.putstatic(syntheticFieldBinding); + } + this.goto_(endLabel); + + + // Generate the body of the exception handler + saveStackSize = stackDepth; + stackDepth = 1; + /* ClassNotFoundException on stack -- the class literal could be doing more things + on the stack, which means that the stack may not be empty at this point in the + above code gen. So we save its state and restart it from 1. */ + + anyExceptionHandler.place(); + + // Transform the current exception, and repush and throw a + // NoClassDefFoundError(ClassNotFound.getMessage()) + + this.newNoClassDefFoundError(); + this.dup_x1(); + this.swap(); + + // Retrieve the message from the old exception + this.invokeThrowableGetMessage(); + + // Send the constructor taking a message string as an argument + this.invokeNoClassDefFoundErrorStringConstructor(); + this.athrow(); + stackDepth = saveStackSize; + endLabel.place(); } - this.goto_(endLabel); - - - // Generate the body of the exception handler - saveStackSize = stackDepth; - stackDepth = 1; - /* ClassNotFoundException on stack -- the class literal could be doing more things - on the stack, which means that the stack may not be empty at this point in the - above code gen. So we save its state and restart it from 1. */ - - anyExceptionHandler.place(); - - // Transform the current exception, and repush and throw a - // NoClassDefFoundError(ClassNotFound.getMessage()) - - this.newNoClassDefFoundError(); - this.dup_x1(); - this.swap(); - - // Retrieve the message from the old exception - this.invokeThrowableGetMessage(); - - // Send the constructor taking a message string as an argument - this.invokeNoClassDefFoundErrorStringConstructor(); - this.athrow(); - endLabel.place(); - stackDepth = saveStackSize; } /** * This method generates the code attribute bytecode @@ -1346,41 +1357,57 @@ final public void generateCodeAttributeForProblemMethod(String problemMessage) { athrow(); } public void generateConstant(Constant constant, int implicitConversionCode) { - int targetTypeID = implicitConversionCode >> 4; - switch (targetTypeID) { - case T_boolean : - generateInlinedValue(constant.booleanValue()); - break; - case T_char : - generateInlinedValue(constant.charValue()); - break; - case T_byte : - generateInlinedValue(constant.byteValue()); - break; - case T_short : - generateInlinedValue(constant.shortValue()); - break; - case T_int : - generateInlinedValue(constant.intValue()); - break; - case T_long : - generateInlinedValue(constant.longValue()); - break; - case T_float : - generateInlinedValue(constant.floatValue()); - break; - case T_double : - generateInlinedValue(constant.doubleValue()); - break; - default : //String or Object - ldc(constant.stringValue()); + int targetTypeID = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4; + if (targetTypeID != 0) { + switch (targetTypeID) { + case T_boolean : + generateInlinedValue(constant.booleanValue()); + break; + case T_char : + generateInlinedValue(constant.charValue()); + break; + case T_byte : + generateInlinedValue(constant.byteValue()); + break; + case T_short : + generateInlinedValue(constant.shortValue()); + break; + case T_int : + generateInlinedValue(constant.intValue()); + break; + case T_long : + generateInlinedValue(constant.longValue()); + break; + case T_float : + generateInlinedValue(constant.floatValue()); + break; + case T_double : + generateInlinedValue(constant.doubleValue()); + break; + case T_JavaLangString : + ldc(constant.stringValue()); + } + } else { + ldc(constant.stringValue()); + } + if ((implicitConversionCode & BOXING) != 0) { + // need boxing + generateBoxingConversion(targetTypeID); } } + /** + * Generates the sequence of instructions which will perform the conversion of the expression + * on the stack into a different type (e.g. long l = someInt; --> i2l must be inserted). * @param implicitConversionCode int */ public void generateImplicitConversion(int implicitConversionCode) { - switch (implicitConversionCode) { + if ((implicitConversionCode & UNBOXING) != 0) { + final int typeId = implicitConversionCode & COMPILE_TYPE_MASK; + generateUnboxingConversion(typeId); + // unboxing can further involve base type conversions + } + switch (implicitConversionCode & IMPLICIT_CONVERSION_MASK) { case Float2Char : this.f2i(); this.i2c(); @@ -1477,6 +1504,11 @@ public void generateImplicitConversion(int implicitConversionCode) { case Float2Long : this.f2l(); } + if ((implicitConversionCode & BOXING) != 0) { + // need to unbox/box the constant + final int typeId = (implicitConversionCode & IMPLICIT_CONVERSION_MASK) >> 4; + generateBoxingConversion(typeId); + } } public void generateInlinedValue(byte inlinedValue) { switch (inlinedValue) { @@ -1699,27 +1731,27 @@ public void generateOuterAccess(Object[] mappingSequence, ASTNode invocationSite * @param oper1 the first expression * @param oper2 the second expression */ -public void generateStringAppend(BlockScope blockScope, Expression oper1, Expression oper2) { +public void generateStringConcatenationAppend(BlockScope blockScope, Expression oper1, Expression oper2) { int pc; if (oper1 == null) { /* Operand is already on the stack, and maybe nil: note type1 is always to java.lang.String here.*/ - this.newStringBuffer(); + this.newStringContatenation(); this.dup_x1(); this.swap(); // If argument is reference type, need to transform it // into a string (handles null case) - this.invokeStringValueOf(T_Object); - this.invokeStringBufferStringConstructor(); + this.invokeStringValueOf(T_JavaLangObject); + this.invokeStringConcatenationStringConstructor(); } else { pc = position; - oper1.generateOptimizedStringBufferCreation(blockScope, this, oper1.implicitConversion & 0xF); + oper1.generateOptimizedStringConcatenationCreation(blockScope, this, oper1.implicitConversion & COMPILE_TYPE_MASK); this.recordPositionsFrom(pc, oper1.sourceStart); } pc = position; - oper2.generateOptimizedStringBuffer(blockScope, this, oper2.implicitConversion & 0xF); + oper2.generateOptimizedStringConcatenation(blockScope, this, oper2.implicitConversion & COMPILE_TYPE_MASK); this.recordPositionsFrom(pc, oper2.sourceStart); - this.invokeStringBufferToString(); + this.invokeStringConcatenationToString(); } /** * Code responsible to generate the suitable code to supply values for the synthetic enclosing @@ -1795,7 +1827,7 @@ public void generateSyntheticOuterArgumentValues(BlockScope currentScope, Refere /** * @param accessBinding the access method binding to generate */ -public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBinding accessBinding) { +public void generateSyntheticBodyForConstructorAccess(SyntheticMethodBinding accessBinding) { initializeMaxLocals(accessBinding); @@ -1804,8 +1836,14 @@ public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBindi int length = parameters.length; int resolvedPosition = 1; this.aload_0(); - if (constructorBinding.declaringClass.isNestedType()) { - NestedTypeBinding nestedType = (NestedTypeBinding) constructorBinding.declaringClass; + // special name&ordinal argument generation for enum constructors + TypeBinding declaringClass = constructorBinding.declaringClass; + if (declaringClass.erasure().id == T_JavaLangEnum || declaringClass.isEnum()) { + this.aload_1(); // pass along name param as name arg + this.iload_2(); // pass along ordinal param as ordinal arg + } + if (declaringClass.isNestedType()) { + NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticEnclosingInstances(); for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) { TypeBinding type; @@ -1824,8 +1862,8 @@ public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBindi resolvedPosition++; } - if (constructorBinding.declaringClass.isNestedType()) { - NestedTypeBinding nestedType = (NestedTypeBinding) constructorBinding.declaringClass; + if (declaringClass.isNestedType()) { + NestedTypeBinding nestedType = (NestedTypeBinding) declaringClass; SyntheticArgumentBinding[] syntheticArguments = nestedType.syntheticOuterLocalVariables(); for (int i = 0; i < (syntheticArguments == null ? 0 : syntheticArguments.length); i++) { TypeBinding type; @@ -1839,7 +1877,82 @@ public void generateSyntheticBodyForConstructorAccess(SyntheticAccessMethodBindi this.invokespecial(constructorBinding); this.return_(); } -public void generateSyntheticBodyForFieldReadAccess(SyntheticAccessMethodBinding accessBinding) { +//static X[] values() { +// X[] values; +// int length; +// X[] result; +// System.arraycopy(values = $VALUES, 0, result = new X[length= values.length], 0, length) +// return result; +//} +public void generateSyntheticBodyForEnumValues(SyntheticMethodBinding methodBinding) { + ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope; + FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield; + initializeMaxLocals(methodBinding); + TypeBinding enumArray = methodBinding.returnType; + + this.getstatic(enumValuesSyntheticfield); + this.dup(); + this.astore_0(); + this.iconst_0(); + this.aload_0(); + this.arraylength(); + this.dup(); + this.istore_1(); + this.newArray((ArrayBinding) enumArray); + this.dup(); + this.astore_2(); + this.iconst_0(); + this.iload_1(); + this.invokeSystemArraycopy(); + this.aload_2(); + this.areturn(); +} +//static X valueOf(String name) { +// X[] values; +// for (int i = (values = $VALUES).length; --i >= 0;) { +// X value; +// if (name.equals(value = values[i].name())) return value; +// } +// throw new IllegalArgumentException(name); +//} +public void generateSyntheticBodyForEnumValueOf(SyntheticMethodBinding methodBinding) { + ClassScope scope = ((SourceTypeBinding)methodBinding.declaringClass).scope; + FieldBinding enumValuesSyntheticfield = scope.referenceContext.enumValuesSyntheticfield; + initializeMaxLocals(methodBinding); + Label loopCond = new Label(this); + Label loopStart = new Label(this); + Label wrongConstant = new Label(this); + + this.getstatic(enumValuesSyntheticfield); + this.dup(); + this.astore_1(); + this.arraylength(); + this.istore_2(); + this.goto_(loopCond); + loopStart.place(); + this.aload_0(); + this.aload_1(); + this.iload_2(); + this.aaload(); + this.dup(); + this.astore_3(); + this.invokeJavaLangEnumname(this.classFile.referenceBinding); + this.invokeStringEquals(); + this.ifeq(wrongConstant); + this.aload_3(); + this.areturn(); + wrongConstant.place(); + loopCond.place(); + this.iinc(2, -1); + this.iload_2(); + this.ifge(loopStart); + this.newJavaLangIllegalArgumentException(); + this.dup(); + this.aload_0(); + this.invokeJavaLangIllegalArgumentExceptionStringConstructor(); + this.athrow(); +} +public void generateSyntheticBodyForFieldReadAccess(SyntheticMethodBinding accessBinding) { initializeMaxLocals(accessBinding); FieldBinding fieldBinding = accessBinding.targetReadField; TypeBinding type; @@ -1866,7 +1979,7 @@ public void generateSyntheticBodyForFieldReadAccess(SyntheticAccessMethodBinding } else this.areturn(); } -public void generateSyntheticBodyForFieldWriteAccess(SyntheticAccessMethodBinding accessBinding) { +public void generateSyntheticBodyForFieldWriteAccess(SyntheticMethodBinding accessBinding) { initializeMaxLocals(accessBinding); FieldBinding fieldBinding = accessBinding.targetWriteField; if (fieldBinding.isStatic()) { @@ -1879,12 +1992,15 @@ public void generateSyntheticBodyForFieldWriteAccess(SyntheticAccessMethodBindin } this.return_(); } -public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding accessBinding) { +public void generateSyntheticBodyForMethodAccess(SyntheticMethodBinding accessBinding) { initializeMaxLocals(accessBinding); MethodBinding methodBinding = accessBinding.targetMethod; TypeBinding[] parameters = methodBinding.parameters; int length = parameters.length; + TypeBinding[] arguments = accessBinding.kind == SyntheticMethodBinding.BridgeMethod + ? accessBinding.parameters + : null; int resolvedPosition; if (methodBinding.isStatic()) resolvedPosition = 0; @@ -1893,8 +2009,16 @@ public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding ac resolvedPosition = 1; } for (int i = 0; i < length; i++) { - load(parameters[i], resolvedPosition); - if ((parameters[i] == DoubleBinding) || (parameters[i] == LongBinding)) + TypeBinding parameter = parameters[i]; + if (arguments != null) { // for bridge methods + TypeBinding argument = arguments[i]; + load(argument, resolvedPosition); + if (argument != parameter) + checkcast(parameter); + } else { + load(parameter, resolvedPosition); + } + if ((parameter == DoubleBinding) || (parameter == LongBinding)) resolvedPosition += 2; else resolvedPosition++; @@ -1906,10 +2030,10 @@ public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding ac if (methodBinding.isConstructor() || methodBinding.isPrivate() // qualified super "X.super.foo()" targets methods from superclass - || accessBinding.accessType == SyntheticAccessMethodBinding.SuperMethodAccess){ + || accessBinding.kind == SyntheticMethodBinding.SuperMethodAccess){ this.invokespecial(methodBinding); } else { - if (methodBinding.declaringClass.isInterface()){ + if ((methodBinding.declaringClass.modifiers & AccInterface) != 0) { // interface or annotation type this.invokeinterface(methodBinding); } else { this.invokevirtual(methodBinding); @@ -1936,6 +2060,172 @@ public void generateSyntheticBodyForMethodAccess(SyntheticAccessMethodBinding ac else this.areturn(); } +public void generateBoxingConversion(int unboxedTypeID) { + switch (unboxedTypeID) { + case T_byte : + // invokestatic: Byte.valueOf(byte) + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangByteConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.byteByteSignature); //$NON-NLS-1$ + break; + case T_short : + // invokestatic: Short.valueOf(short) + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangShortConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.shortShortSignature); //$NON-NLS-1$ + break; + case T_char : + // invokestatic: Character.valueOf(char) + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangCharacterConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.charCharacterSignature); //$NON-NLS-1$ + break; + case T_int : + // invokestatic: Integer.valueOf(int) + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangIntegerConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.IntIntegerSignature); //$NON-NLS-1$ + break; + case T_long : + // invokestatic: Long.valueOf(long) + this.invoke( + OPC_invokestatic, + 2, // argCount + 1, // return type size + ConstantPool.JavaLangLongConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.longLongSignature); //$NON-NLS-1$ + break; + case T_float : + // invokestatic: Float.valueOf(float) + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangFloatConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.floatFloatSignature); //$NON-NLS-1$ + break; + case T_double : + // invokestatic: Double.valueOf(double) + this.invoke( + OPC_invokestatic, + 2, // argCount + 1, // return type size + ConstantPool.JavaLangDoubleConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.doubleDoubleSignature); //$NON-NLS-1$ + break; + case T_boolean : + // invokestatic: Boolean.valueOf(boolean) + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangBooleanConstantPoolName, + ConstantPool.ValueOf, + ConstantPool.booleanBooleanSignature); //$NON-NLS-1$ + } +} +public void generateUnboxingConversion(int unboxedTypeID) { + switch (unboxedTypeID) { + case T_byte : + // invokevirtual: byteValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangByteConstantPoolName, + ConstantPool.BYTEVALUE_BYTE_METHOD_NAME, + ConstantPool.BYTEVALUE_BYTE_METHOD_SIGNATURE); + break; + case T_short : + // invokevirtual: shortValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangShortConstantPoolName, + ConstantPool.SHORTVALUE_SHORT_METHOD_NAME, + ConstantPool.SHORTVALUE_SHORT_METHOD_SIGNATURE); + break; + case T_char : + // invokevirtual: charValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangCharacterConstantPoolName, + ConstantPool.CHARVALUE_CHARACTER_METHOD_NAME, + ConstantPool.CHARVALUE_CHARACTER_METHOD_SIGNATURE); + break; + case T_int : + // invokevirtual: intValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangIntegerConstantPoolName, + ConstantPool.INTVALUE_INTEGER_METHOD_NAME, + ConstantPool.INTVALUE_INTEGER_METHOD_SIGNATURE); + break; + case T_long : + // invokevirtual: longValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 2, // return type size + ConstantPool.JavaLangLongConstantPoolName, + ConstantPool.LONGVALUE_LONG_METHOD_NAME, + ConstantPool.LONGVALUE_LONG_METHOD_SIGNATURE); + break; + case T_float : + // invokevirtual: floatValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangFloatConstantPoolName, + ConstantPool.FLOATVALUE_FLOAT_METHOD_NAME, + ConstantPool.FLOATVALUE_FLOAT_METHOD_SIGNATURE); + break; + case T_double : + // invokevirtual: doubleValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 2, // return type size + ConstantPool.JavaLangDoubleConstantPoolName, + ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_NAME, + ConstantPool.DOUBLEVALUE_DOUBLE_METHOD_SIGNATURE); + break; + case T_boolean : + // invokevirtual: booleanValue() + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangBooleanConstantPoolName, + ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_NAME, + ConstantPool.BOOLEANVALUE_BOOLEAN_METHOD_SIGNATURE); + } +} final public byte[] getContents() { byte[] contents; System.arraycopy(bCodeStream, 0, contents = new byte[position], 0, position); @@ -1943,88 +2233,161 @@ final public byte[] getContents() { } final public void getfield(FieldBinding fieldBinding) { if (DEBUG) System.out.println(position + "\t\tgetfield:"+fieldBinding); //$NON-NLS-1$ - countLabels = 0; + int returnTypeSize = 1; if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) { - if (++stackDepth > stackMax) - stackMax = stackDepth; + returnTypeSize = 2; + } + generateFieldAccess( + OPC_getfield, + returnTypeSize, + fieldBinding.declaringClass.constantPoolName(), + fieldBinding.name, + fieldBinding.type.signature()); +} +private void generateFieldAccess(byte opcode, int returnTypeSize, char[] declaringClass, char[] name, char[] signature) { + countLabels = 0; + switch(opcode) { + case OPC_getfield : + if (returnTypeSize == 2) { + stackDepth++; + } + break; + case OPC_getstatic : + if (returnTypeSize == 2) { + stackDepth += 2; + } else { + stackDepth++; + } + break; + case OPC_putfield : + if (returnTypeSize == 2) { + stackDepth -= 3; + } else { + stackDepth -= 2; + } + break; + case OPC_putstatic : + if (returnTypeSize == 2) { + stackDepth -= 2; + } else { + stackDepth--; + } + } + if (stackDepth > stackMax) { + stackMax = stackDepth; } if (classFileOffset + 2 >= bCodeStream.length) { resizeByteArray(); } position++; - bCodeStream[classFileOffset++] = OPC_getfield; - writeUnsignedShort(constantPool.literalIndex(fieldBinding)); + bCodeStream[classFileOffset++] = opcode; + writeUnsignedShort(constantPool.literalIndexForField(declaringClass, name, signature)); } final public void getstatic(FieldBinding fieldBinding) { if (DEBUG) System.out.println(position + "\t\tgetstatic:"+fieldBinding); //$NON-NLS-1$ - countLabels = 0; - if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) - stackDepth += 2; - else - stackDepth += 1; - if (stackDepth > stackMax) - stackMax = stackDepth; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + int returnTypeSize = 1; + if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) { + returnTypeSize = 2; } - position++; - bCodeStream[classFileOffset++] = OPC_getstatic; - writeUnsignedShort(constantPool.literalIndex(fieldBinding)); + generateFieldAccess( + OPC_getstatic, + returnTypeSize, + fieldBinding.declaringClass.constantPoolName(), + fieldBinding.name, + fieldBinding.type.signature()); } public void getTYPE(int baseTypeID) { countLabels = 0; - if (++stackDepth > stackMax) - stackMax = stackDepth; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_getstatic; switch (baseTypeID) { case T_byte : // getstatic: java.lang.Byte.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Byte.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangByteTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangByteConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_short : // getstatic: java.lang.Short.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Short.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangShortTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangShortConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_char : // getstatic: java.lang.Character.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Character.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangCharacterTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangCharacterConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_int : // getstatic: java.lang.Integer.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Integer.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangIntegerTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangIntegerConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_long : // getstatic: java.lang.Long.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Long.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangLongTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangLongConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_float : // getstatic: java.lang.Float.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Float.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangFloatTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangFloatConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_double : // getstatic: java.lang.Double.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Double.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangDoubleTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangDoubleConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_boolean : // getstatic: java.lang.Boolean.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Boolean.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangBooleanTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangBooleanConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; case T_void : // getstatic: java.lang.Void.TYPE if (DEBUG) System.out.println(position + "\t\tgetstatic: java.lang.Void.TYPE"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangVoidTYPE()); + generateFieldAccess( + OPC_getstatic, + 1, + ConstantPool.JavaLangVoidConstantPoolName, + ConstantPool.TYPE, + ConstantPool.JavaLangClassSignature); break; } } @@ -2691,7 +3054,8 @@ public void init(ClassFile targetClassFile) { noExceptionHandlers = new ExceptionLabel[length]; } System.arraycopy(noExceptionHandlers, 0, exceptionHandlers, 0, length); - exceptionHandlersNumber = 0; + exceptionHandlersIndex = 0; + exceptionHandlersCounter = 0; length = labels.length; if (noLabels.length < length) { @@ -2710,41 +3074,50 @@ public void init(ClassFile targetClassFile) { */ public void initializeMaxLocals(MethodBinding methodBinding) { - maxLocals = (methodBinding == null || methodBinding.isStatic()) ? 0 : 1; + if (methodBinding == null) { + this.maxLocals = 0; + return; + } + + this.maxLocals = methodBinding.isStatic() ? 0 : 1; + + // take into account enum constructor synthetic name+ordinal + if (methodBinding.isConstructor() && methodBinding.declaringClass.isEnum()) { + this.maxLocals += 2; // String and int (enum constant name+ordinal) + } + // take into account the synthetic parameters - if (methodBinding != null) { - if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) { - ReferenceBinding enclosingInstanceTypes[]; - if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) { - for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) { - maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be - // LongBinding or DoubleBinding - } - } - SyntheticArgumentBinding syntheticArguments[]; - if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) { - for (int i = 0, max = syntheticArguments.length; i < max; i++) { - TypeBinding argType; - if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) { - maxLocals += 2; - } else { - maxLocals++; - } - } + if (methodBinding.isConstructor() && methodBinding.declaringClass.isNestedType()) { + ReferenceBinding enclosingInstanceTypes[]; + if ((enclosingInstanceTypes = methodBinding.declaringClass.syntheticEnclosingInstanceTypes()) != null) { + for (int i = 0, max = enclosingInstanceTypes.length; i < max; i++) { + this.maxLocals++; // an enclosingInstanceType can only be a reference binding. It cannot be + // LongBinding or DoubleBinding } } - TypeBinding[] arguments; - if ((arguments = methodBinding.parameters) != null) { - for (int i = 0, max = arguments.length; i < max; i++) { + SyntheticArgumentBinding syntheticArguments[]; + if ((syntheticArguments = methodBinding.declaringClass.syntheticOuterLocalVariables()) != null) { + for (int i = 0, max = syntheticArguments.length; i < max; i++) { TypeBinding argType; - if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) { - maxLocals += 2; + if (((argType = syntheticArguments[i].type) == LongBinding) || (argType == DoubleBinding)) { + this.maxLocals += 2; } else { - maxLocals++; + this.maxLocals++; } } } } + TypeBinding[] arguments; + if ((arguments = methodBinding.parameters) != null) { + for (int i = 0, max = arguments.length; i < max; i++) { + TypeBinding argType; + if (((argType = arguments[i]) == LongBinding) || (argType == DoubleBinding)) { + this.maxLocals += 2; + } else { + this.maxLocals++; + } + } + } } /** * This methods searches for an existing entry inside the pcToSourceMap table with a pc equals to @pc. @@ -2792,45 +3165,53 @@ final public void instance_of(TypeBinding typeBinding) { } position++; bCodeStream[classFileOffset++] = OPC_instanceof; - writeUnsignedShort(constantPool.literalIndex(typeBinding)); + writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName())); } public void invokeClassForName() { // invokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class; if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.Class.forName(Ljava.lang.String;)Ljava.lang.Class;"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokestatic; - writeUnsignedShort(constantPool.literalIndexForJavaLangClassForName()); + this.invoke( + OPC_invokestatic, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangClassConstantPoolName, + ConstantPool.ForName, + ConstantPool.ForNameSignature); } - public void invokeJavaLangClassDesiredAssertionStatus() { // invokevirtual: java.lang.Class.desiredAssertionStatus()Z; if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.desiredAssertionStatus()Z;"); //$NON-NLS-1$ - countLabels = 0; - stackDepth--; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangClassDesiredAssertionStatus()); + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangClassConstantPoolName, + ConstantPool.DesiredAssertionStatus, + ConstantPool.DesiredAssertionStatusSignature); } public void invokeJavaLangClassGetComponentType() { // invokevirtual: java.lang.Class.getComponentType()java.lang.Class; if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Class.getComponentType()java.lang.Class;"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangClassGetComponentType()); + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangClassConstantPoolName, + ConstantPool.GetComponentType, + ConstantPool.GetComponentTypeSignature); +} +public void invokeEnumOrdinal(char[] enumTypeConstantPoolName) { + // invokevirtual: .ordinal() + if (DEBUG) System.out.println(position + "\t\tinvokevirtual: "+new String(enumTypeConstantPoolName)+".ordinal()"); //$NON-NLS-1$ //$NON-NLS-2$ + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + enumTypeConstantPoolName, + ConstantPool.Ordinal, + ConstantPool.OrdinalSignature); } - final public void invokeinterface(MethodBinding methodBinding) { // initialized to 1 to take into account this immediately if (DEBUG) System.out.println(position + "\t\tinvokeinterface: " + methodBinding); //$NON-NLS-1$ @@ -2868,37 +3249,35 @@ final public void invokeinterface(MethodBinding methodBinding) { public void invokeJavaLangErrorConstructor() { // invokespecial: java.lang.Error(Ljava.lang.String;)V if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.Error(Ljava.lang.String;)V"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokespecial; - stackDepth -= 2; - writeUnsignedShort(constantPool.literalIndexForJavaLangErrorConstructor()); + this.invoke( + OPC_invokespecial, + 1, // argCount + 0, // return type size + ConstantPool.JavaLangErrorConstantPoolName, + ConstantPool.Init, + ConstantPool.StringConstructorSignature); } public void invokeNoClassDefFoundErrorStringConstructor() { // invokespecial: java.lang.NoClassDefFoundError.(Ljava.lang.String;)V if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.NoClassDefFoundError.(Ljava.lang.String;)V"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokespecial; - stackDepth -= 2; - writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundErrorStringConstructor()); + this.invoke( + OPC_invokespecial, + 1, // argCount + 0, // return type size + ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName, + ConstantPool.Init, + ConstantPool.StringConstructorSignature); } public void invokeObjectGetClass() { // invokevirtual: java.lang.Object.getClass()Ljava.lang.Class; if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Object.getClass()Ljava.lang.Class;"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangObjectGetClass()); + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangObjectConstantPoolName, + ConstantPool.GetClass, + ConstantPool.GetClassSignature); } final public void invokespecial(MethodBinding methodBinding) { @@ -2984,121 +3363,393 @@ final public void invokestatic(MethodBinding methodBinding) { * The equivalent code performs a string conversion of the TOS * @param typeID int */ -public void invokeStringBufferAppendForType(int typeID) { - if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$ - countLabels = 0; - int usedTypeID; - if (typeID == T_null) - usedTypeID = T_String; - else - usedTypeID = typeID; - // invokevirtual - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); +public void invokeStringConcatenationAppendForType(int typeID) { + if (DEBUG) { + if (this.targetLevel >= JDK1_5) { + System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuilder.append(...)"); //$NON-NLS-1$ + } else { + System.out.println(position + "\t\tinvokevirtual: java.lang.StringBuffer.append(...)"); //$NON-NLS-1$ + } } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferAppend(typeID)); - if ((usedTypeID == T_long) || (usedTypeID == T_double)) - stackDepth -= 2; - else - stackDepth--; + int argCount = 1; + int returnType = 1; + char[] declarinClass = null; + char[] selector = ConstantPool.Append; + char[] signature = null; + switch (typeID) { + case T_int : + case T_byte : + case T_short : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendIntSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendIntSignature; + } + break; + case T_long : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendLongSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendLongSignature; + } + argCount = 2; + break; + case T_float : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendFloatSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendFloatSignature; + } + break; + case T_double : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendDoubleSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendDoubleSignature; + } + argCount = 2; + break; + case T_char : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendCharSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendCharSignature; + } + break; + case T_boolean : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendBooleanSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendBooleanSignature; + } + break; + case T_undefined : + case T_JavaLangObject : + case T_null : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendObjectSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendObjectSignature; + } + break; + case T_JavaLangString : + if (this.targetLevel >= JDK1_5) { + declarinClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + signature = ConstantPool.StringBuilderAppendStringSignature; + } else { + declarinClass = ConstantPool.JavaLangStringBufferConstantPoolName; + signature = ConstantPool.StringBufferAppendStringSignature; + } + break; + } + this.invoke( + OPC_invokevirtual, + argCount, // argCount + returnType, // return type size + declarinClass, + selector, + signature); } public void invokeJavaLangAssertionErrorConstructor(int typeBindingID) { // invokespecial: java.lang.AssertionError.(typeBindingID)V if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.(typeBindingID)V"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + int argCount = 1; + char[] signature = null; + switch (typeBindingID) { + case T_int : + case T_byte : + case T_short : + signature = ConstantPool.IntConstrSignature; + break; + case T_long : + signature = ConstantPool.LongConstrSignature; + argCount = 2; + break; + case T_float : + signature = ConstantPool.FloatConstrSignature; + break; + case T_double : + signature = ConstantPool.DoubleConstrSignature; + argCount = 2; + break; + case T_char : + signature = ConstantPool.CharConstrSignature; + break; + case T_boolean : + signature = ConstantPool.BooleanConstrSignature; + break; + case T_JavaLangObject : + case T_JavaLangString : + case T_null : + signature = ConstantPool.ObjectConstrSignature; + break; } - position++; - bCodeStream[classFileOffset++] = OPC_invokespecial; - writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionErrorConstructor(typeBindingID)); - stackDepth -= 2; + this.invoke( + OPC_invokespecial, + argCount, // argCount + 0, // return type size + ConstantPool.JavaLangAssertionErrorConstantPoolName, + ConstantPool.Init, + signature); } public void invokeJavaLangAssertionErrorDefaultConstructor() { // invokespecial: java.lang.AssertionError.()V if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.AssertionError.()V"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokespecial; - writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionErrorDefaultConstructor()); - stackDepth --; + this.invoke( + OPC_invokespecial, + 0, // argCount + 0, // return type size + ConstantPool.JavaLangAssertionErrorConstantPoolName, + ConstantPool.Init, + ConstantPool.DefaultConstructorSignature); +} +public void invokeJavaLangEnumname(TypeBinding typeBinding) { + // invokevirtual: java.lang.Enum.name()String + if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Enum.name()Ljava/lang/String;"); //$NON-NLS-1$ + this.invoke( + OPC_invokevirtual, + 0, + 1, + typeBinding.constantPoolName(), + ConstantPool.Name, + ConstantPool.NameSignature); +} +public void invokeJavaLangIllegalArgumentExceptionStringConstructor() { + // invokespecial: java.lang.IllegalArgumentException.(String)V + if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.IllegalArgumentException.(java.lang.String)V"); //$NON-NLS-1$ + this.invoke( + OPC_invokespecial, + 1, // argCount + 0, // return type size + ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName, + ConstantPool.Init, + ConstantPool.StringConstructorSignature); } -public void invokeStringBufferDefaultConstructor() { +public void invokeJavaUtilIteratorHasNext() { + // invokeinterface java.util.Iterator.hasNext()Z + if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.hasNext()Z"); //$NON-NLS-1$ + this.invoke( + OPC_invokeinterface, + 0, // argCount + 1, // return type size + ConstantPool.JavaUtilIteratorConstantPoolName, + ConstantPool.HasNext, + ConstantPool.HasNextSignature); +} +public void invokeJavaUtilIteratorNext() { + // invokeinterface java.util.Iterator.next()java.lang.Object + if (DEBUG) System.out.println(position + "\t\tinvokeinterface: java.util.Iterator.next()java.lang.Object"); //$NON-NLS-1$ + this.invoke( + OPC_invokeinterface, + 0, // argCount + 1, // return type size + ConstantPool.JavaUtilIteratorConstantPoolName, + ConstantPool.Next, + ConstantPool.NextSignature); +} +public void invokeStringConcatenationDefaultConstructor() { // invokespecial: java.lang.StringBuffer.()V - if (DEBUG) System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.()V"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + if (DEBUG) { + if (this.targetLevel >= JDK1_5) { + System.out.println(position + "\t\tinvokespecial: java.lang.StringBuilder.()V"); //$NON-NLS-1$ + } else { + System.out.println(position + "\t\tinvokespecial: java.lang.StringBuffer.()V"); //$NON-NLS-1$ + } } - position++; - bCodeStream[classFileOffset++] = OPC_invokespecial; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferDefaultConstructor()); - stackDepth--; -} -public void invokeStringBufferStringConstructor() { - // invokespecial: java.lang.StringBuffer.(Ljava.lang.String;)V - if (DEBUG) System.out.println(position + "\t\tjava.lang.StringBuffer.(Ljava.lang.String;)V"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName; + if (this.targetLevel >= JDK1_5) { + declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + } + this.invoke( + OPC_invokespecial, + 0, // argCount + 0, // return type size + declaringClass, + ConstantPool.Init, + ConstantPool.DefaultConstructorSignature); +} +public void invokeStringConcatenationStringConstructor() { + if (DEBUG) { + if (this.targetLevel >= JDK1_5) { + System.out.println(position + "\t\tjava.lang.StringBuilder.(Ljava.lang.String;)V"); //$NON-NLS-1$ + } else { + System.out.println(position + "\t\tjava.lang.StringBuffer.(Ljava.lang.String;)V"); //$NON-NLS-1$ + } } - position++; - bCodeStream[classFileOffset++] = OPC_invokespecial; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferConstructor()); - stackDepth -= 2; + char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName; + if (this.targetLevel >= JDK1_5) { + declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + } + this.invoke( + OPC_invokespecial, + 1, // argCount + 0, // return type size + declaringClass, + ConstantPool.Init, + ConstantPool.StringConstructorSignature); } -public void invokeStringBufferToString() { - // invokevirtual: StringBuffer.toString()Ljava.lang.String; - if (DEBUG) System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); +public void invokeStringConcatenationToString() { + if (DEBUG) { + if (this.targetLevel >= JDK1_5) { + System.out.println(position + "\t\tinvokevirtual: StringBuilder.toString()Ljava.lang.String;"); //$NON-NLS-1$ + } else { + System.out.println(position + "\t\tinvokevirtual: StringBuffer.toString()Ljava.lang.String;"); //$NON-NLS-1$ + } } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringBufferToString()); + char[] declaringClass = ConstantPool.JavaLangStringBufferConstantPoolName; + if (this.targetLevel >= JDK1_5) { + declaringClass = ConstantPool.JavaLangStringBuilderConstantPoolName; + } + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + declaringClass, + ConstantPool.ToString, + ConstantPool.ToStringSignature); +} +public void invokeStringEquals() { + // invokevirtual: java.lang.String.equals(java.lang.Object) + if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.equals(...)"); //$NON-NLS-1$ + this.invoke( + OPC_invokevirtual, + 1, // argCount + 1, // return type size + ConstantPool.JavaLangStringConstantPoolName, + ConstantPool.Equals, + ConstantPool.EqualsSignature); } public void invokeStringIntern() { // invokevirtual: java.lang.String.intern() if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.String.intern()"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringIntern()); + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangStringConstantPoolName, + ConstantPool.Intern, + ConstantPool.InternSignature); } public void invokeStringValueOf(int typeID) { // invokestatic: java.lang.String.valueOf(argumentType) if (DEBUG) System.out.println(position + "\t\tinvokestatic: java.lang.String.valueOf(...)"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); - } - position++; - bCodeStream[classFileOffset++] = OPC_invokestatic; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringValueOf(typeID)); + int argCount = 1; + char[] signature = null; + switch (typeID) { + case T_int : + case T_byte : + case T_short : + signature = ConstantPool.ValueOfIntSignature; + break; + case T_long : + signature = ConstantPool.ValueOfLongSignature; + argCount = 2; + break; + case T_float : + signature = ConstantPool.ValueOfFloatSignature; + break; + case T_double : + signature = ConstantPool.ValueOfDoubleSignature; + argCount = 2; + break; + case T_char : + signature = ConstantPool.ValueOfCharSignature; + break; + case T_boolean : + signature = ConstantPool.ValueOfBooleanSignature; + break; + case T_JavaLangObject : + case T_JavaLangString : + case T_null : + case T_undefined : + signature = ConstantPool.ValueOfObjectSignature; + break; + } + this.invoke( + OPC_invokestatic, + argCount, // argCount + 1, // return type size + ConstantPool.JavaLangStringConstantPoolName, + ConstantPool.ValueOf, + signature); +} +public void invokeSystemArraycopy() { + // invokestatic #21 + if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V"); //$NON-NLS-1$ + this.invoke( + OPC_invokestatic, + 5, // argCount + 0, // return type size + ConstantPool.JavaLangSystemConstantPoolName, + ConstantPool.ArrayCopy, + ConstantPool.ArrayCopySignature); } public void invokeThrowableGetMessage() { // invokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String; if (DEBUG) System.out.println(position + "\t\tinvokevirtual: java.lang.Throwable.getMessage()Ljava.lang.String;"); //$NON-NLS-1$ - countLabels = 0; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + this.invoke( + OPC_invokevirtual, + 0, // argCount + 1, // return type size + ConstantPool.JavaLangThrowableConstantPoolName, + ConstantPool.GetMessage, + ConstantPool.GetMessageSignature); +} +final public void invoke(int opcode, int argsSize, int returnTypeSize, char[] declaringClass, char[] selector, char[] signature) { + countLabels = 0; + int argCount = argsSize; + switch(opcode) { + case OPC_invokeinterface : + if (classFileOffset + 4 >= bCodeStream.length) { + resizeByteArray(); + } + position +=3; + bCodeStream[classFileOffset++] = OPC_invokeinterface; + writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, true)); + argCount++; + bCodeStream[classFileOffset++] = (byte) argCount; + bCodeStream[classFileOffset++] = 0; + break; + case OPC_invokevirtual : + case OPC_invokespecial : + if (classFileOffset + 2 >= bCodeStream.length) { + resizeByteArray(); + } + position++; + bCodeStream[classFileOffset++] = (byte) opcode; + writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false)); + argCount++; + break; + case OPC_invokestatic : + if (classFileOffset + 2 >= bCodeStream.length) { + resizeByteArray(); + } + position++; + bCodeStream[classFileOffset++] = OPC_invokestatic; + writeUnsignedShort(constantPool.literalIndexForMethod(declaringClass, selector, signature, false)); + } + stackDepth += returnTypeSize - argCount; + if (stackDepth > stackMax) { + stackMax = stackDepth; } - position++; - bCodeStream[classFileOffset++] = OPC_invokevirtual; - writeUnsignedShort(constantPool.literalIndexForJavaLangThrowableGetMessage()); } final public void invokevirtual(MethodBinding methodBinding) { if (DEBUG) System.out.println(position + "\t\tinvokevirtual:"+methodBinding); //$NON-NLS-1$ @@ -3433,13 +4084,13 @@ final public void lconst_1() { bCodeStream[classFileOffset++] = OPC_lconst_1; } final public void ldc(float constant) { - if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$ countLabels = 0; int index = constantPool.literalIndex(constant); stackDepth++; if (stackDepth > stackMax) stackMax = stackDepth; if (index > 255) { + if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$ // Generate a ldc_w if (classFileOffset + 2 >= bCodeStream.length) { resizeByteArray(); @@ -3448,6 +4099,7 @@ final public void ldc(float constant) { bCodeStream[classFileOffset++] = OPC_ldc_w; writeUnsignedShort(index); } else { + if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$ // Generate a ldc if (classFileOffset + 1 >= bCodeStream.length) { resizeByteArray(); @@ -3458,13 +4110,13 @@ final public void ldc(float constant) { } } final public void ldc(int constant) { - if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$ countLabels = 0; int index = constantPool.literalIndex(constant); stackDepth++; if (stackDepth > stackMax) stackMax = stackDepth; if (index > 255) { + if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$ // Generate a ldc_w if (classFileOffset + 2 >= bCodeStream.length) { resizeByteArray(); @@ -3473,6 +4125,7 @@ final public void ldc(int constant) { bCodeStream[classFileOffset++] = OPC_ldc_w; writeUnsignedShort(index); } else { + if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$ // Generate a ldc if (classFileOffset + 1 >= bCodeStream.length) { resizeByteArray(); @@ -3483,7 +4136,6 @@ final public void ldc(int constant) { } } final public void ldc(String constant) { - if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$ countLabels = 0; int currentConstantPoolIndex = constantPool.currentIndex; int currentConstantPoolOffset = constantPool.currentOffset; @@ -3496,6 +4148,7 @@ final public void ldc(String constant) { if (stackDepth > stackMax) stackMax = stackDepth; if (index > 255) { + if (DEBUG) System.out.println(position + "\t\tldc_w:"+constant); //$NON-NLS-1$ // Generate a ldc_w if (classFileOffset + 2 >= bCodeStream.length) { resizeByteArray(); @@ -3504,6 +4157,7 @@ final public void ldc(String constant) { bCodeStream[classFileOffset++] = OPC_ldc_w; writeUnsignedShort(index); } else { + if (DEBUG) System.out.println(position + "\t\tldc:"+constant); //$NON-NLS-1$ // Generate a ldc if (classFileOffset + 1 >= bCodeStream.length) { resizeByteArray(); @@ -3554,7 +4208,7 @@ final public void ldc(String constant) { } // check if all the string is encoded (PR 1PR2DWJ) // the string is too big to be encoded in one pass - newStringBuffer(); + newStringContatenation(); dup(); // write the first part char[] subChars = new char[i]; @@ -3582,7 +4236,7 @@ final public void ldc(String constant) { bCodeStream[classFileOffset++] = (byte) index; } // write the remaining part - invokeStringBufferStringConstructor(); + invokeStringConcatenationStringConstructor(); while (i < constantLength) { length = 0; utf8encoding = new byte[Math.min(constantLength - i + 100, 65535)]; @@ -3637,12 +4291,38 @@ final public void ldc(String constant) { bCodeStream[classFileOffset++] = (byte) index; } // now on the stack it should be a StringBuffer and a string. - invokeStringBufferAppendForType(T_String); + invokeStringConcatenationAppendForType(T_JavaLangString); } - invokeStringBufferToString(); + invokeStringConcatenationToString(); invokeStringIntern(); } } +final public void ldc(TypeBinding typeBinding) { + countLabels = 0; + int index = constantPool.literalIndexForType(typeBinding.constantPoolName()); + stackDepth++; + if (stackDepth > stackMax) + stackMax = stackDepth; + if (index > 255) { + if (DEBUG) System.out.println(position + "\t\tldc_w:"+ typeBinding); //$NON-NLS-1$ + // Generate a ldc_w + if (classFileOffset + 2 >= bCodeStream.length) { + resizeByteArray(); + } + position++; + bCodeStream[classFileOffset++] = OPC_ldc_w; + writeUnsignedShort(index); + } else { + if (DEBUG) System.out.println(position + "\t\tldw:"+ typeBinding); //$NON-NLS-1$ + // Generate a ldc + if (classFileOffset + 1 >= bCodeStream.length) { + resizeByteArray(); + } + position += 2; + bCodeStream[classFileOffset++] = OPC_ldc; + bCodeStream[classFileOffset++] = (byte) index; + } +} final public void ldc2_w(double constant) { if (DEBUG) System.out.println(position + "\t\tldc2_w:"+constant); //$NON-NLS-1$ countLabels = 0; @@ -4287,14 +4967,14 @@ final public void multianewarray(TypeBinding typeBinding, int dimensions) { } position += 2; bCodeStream[classFileOffset++] = OPC_multianewarray; - writeUnsignedShort(constantPool.literalIndex(typeBinding)); + writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName())); bCodeStream[classFileOffset++] = (byte) dimensions; } /** * We didn't call it new, because there is a conflit with the new keyword */ final public void new_(TypeBinding typeBinding) { - if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding); //$NON-NLS-1$ + if (DEBUG) System.out.println(position + "\t\tnew:"+typeBinding.debugName()); //$NON-NLS-1$ countLabels = 0; stackDepth++; if (stackDepth > stackMax) @@ -4304,7 +4984,7 @@ final public void new_(TypeBinding typeBinding) { } position++; bCodeStream[classFileOffset++] = OPC_new; - writeUnsignedShort(constantPool.literalIndex(typeBinding)); + writeUnsignedShort(constantPool.literalIndexForType(typeBinding.constantPoolName())); } final public void newarray(int array_Type) { if (DEBUG) System.out.println(position + "\t\tnewarray:"+array_Type); //$NON-NLS-1$ @@ -4316,32 +4996,32 @@ final public void newarray(int array_Type) { bCodeStream[classFileOffset++] = OPC_newarray; bCodeStream[classFileOffset++] = (byte) array_Type; } -public void newArray(Scope scope, ArrayBinding arrayBinding) { - TypeBinding component = arrayBinding.elementsType(scope); +public void newArray(ArrayBinding arrayBinding) { + TypeBinding component = arrayBinding.elementsType(); switch (component.id) { case T_int : - this.newarray(10); + this.newarray(INT_ARRAY); break; case T_byte : - this.newarray(8); + this.newarray(BYTE_ARRAY); break; case T_boolean : - this.newarray(4); + this.newarray(BOOLEAN_ARRAY); break; case T_short : - this.newarray(9); + this.newarray(SHORT_ARRAY); break; case T_char : - this.newarray(5); + this.newarray(CHAR_ARRAY); break; case T_long : - this.newarray(11); + this.newarray(LONG_ARRAY); break; case T_float : - this.newarray(6); + this.newarray(FLOAT_ARRAY); break; case T_double : - this.newarray(7); + this.newarray(DOUBLE_ARRAY); break; default : this.anewarray(component); @@ -4359,7 +5039,7 @@ public void newJavaLangError() { } position++; bCodeStream[classFileOffset++] = OPC_new; - writeUnsignedShort(constantPool.literalIndexForJavaLangError()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangErrorConstantPoolName)); } public void newJavaLangAssertionError() { @@ -4374,9 +5054,22 @@ public void newJavaLangAssertionError() { } position++; bCodeStream[classFileOffset++] = OPC_new; - writeUnsignedShort(constantPool.literalIndexForJavaLangAssertionError()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangAssertionErrorConstantPoolName)); +} +public void newJavaLangIllegalArgumentException() { + // new: java.lang.IllegalArgumentException + if (DEBUG) System.out.println(position + "\t\tnew: java.lang.IllegalArgumentException"); //$NON-NLS-1$ + countLabels = 0; + stackDepth++; + if (stackDepth > stackMax) + stackMax = stackDepth; + if (classFileOffset + 2 >= bCodeStream.length) { + resizeByteArray(); + } + position++; + bCodeStream[classFileOffset++] = OPC_new; + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIllegalArgumentExceptionConstantPoolName)); } - public void newNoClassDefFoundError() { // new: java.lang.NoClassDefFoundError if (DEBUG) System.out.println(position + "\t\tnew: java.lang.NoClassDefFoundError"); //$NON-NLS-1$ @@ -4389,21 +5082,33 @@ public void newNoClassDefFoundError() { } position++; bCodeStream[classFileOffset++] = OPC_new; - writeUnsignedShort(constantPool.literalIndexForJavaLangNoClassDefFoundError()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangNoClassDefFoundErrorConstantPoolName)); } -public void newStringBuffer() { +public void newStringContatenation() { // new: java.lang.StringBuffer - if (DEBUG) System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$ + // new: java.lang.StringBuilder + if (DEBUG) { + if (this.targetLevel >= JDK1_5) { + System.out.println(position + "\t\tnew: java.lang.StringBuilder"); //$NON-NLS-1$ + } else { + System.out.println(position + "\t\tnew: java.lang.StringBuffer"); //$NON-NLS-1$ + } + } countLabels = 0; stackDepth++; - if (stackDepth > stackMax) + if (stackDepth > stackMax) { stackMax = stackDepth; + } if (classFileOffset + 2 >= bCodeStream.length) { resizeByteArray(); } position++; bCodeStream[classFileOffset++] = OPC_new; - writeUnsignedShort(constantPool.literalIndexForJavaLangStringBuffer()); + if (this.targetLevel >= JDK1_5) { + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBuilderConstantPoolName)); + } else { + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangStringBufferConstantPoolName)); + } } public void newWrapperFor(int typeID) { countLabels = 0; @@ -4418,39 +5123,39 @@ public void newWrapperFor(int typeID) { switch (typeID) { case T_int : // new: java.lang.Integer if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Integer"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangInteger()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangIntegerConstantPoolName)); break; case T_boolean : // new: java.lang.Boolean if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Boolean"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangBoolean()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangBooleanConstantPoolName)); break; case T_byte : // new: java.lang.Byte if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Byte"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangByte()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangByteConstantPoolName)); break; case T_char : // new: java.lang.Character if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Character"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangCharacter()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangCharacterConstantPoolName)); break; case T_float : // new: java.lang.Float if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Float"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangFloat()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangFloatConstantPoolName)); break; case T_double : // new: java.lang.Double if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Double"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangDouble()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangDoubleConstantPoolName)); break; case T_short : // new: java.lang.Short if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Short"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangShort()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangShortConstantPoolName)); break; case T_long : // new: java.lang.Long if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Long"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangLong()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangLongConstantPoolName)); break; case T_void : // new: java.lang.Void if (DEBUG) System.out.println(position + "\t\tnew: java.lang.Void"); //$NON-NLS-1$ - writeUnsignedShort(constantPool.literalIndexForJavaLangVoid()); + writeUnsignedShort(constantPool.literalIndexForType(ConstantPool.JavaLangVoidConstantPoolName)); } } final public void nop() { @@ -4484,37 +5189,29 @@ final public void pop2() { } final public void putfield(FieldBinding fieldBinding) { if (DEBUG) System.out.println(position + "\t\tputfield:"+fieldBinding); //$NON-NLS-1$ - countLabels = 0; - int id; - if (((id = fieldBinding.type.id) == T_double) || (id == T_long)) - stackDepth -= 3; - else - stackDepth -= 2; - if (stackDepth > stackMax) - stackMax = stackDepth; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + int returnTypeSize = 1; + if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) { + returnTypeSize = 2; } - position++; - bCodeStream[classFileOffset++] = OPC_putfield; - writeUnsignedShort(constantPool.literalIndex(fieldBinding)); + generateFieldAccess( + OPC_putfield, + returnTypeSize, + fieldBinding.declaringClass.constantPoolName(), + fieldBinding.name, + fieldBinding.type.signature()); } final public void putstatic(FieldBinding fieldBinding) { if (DEBUG) System.out.println(position + "\t\tputstatic:"+fieldBinding); //$NON-NLS-1$ - countLabels = 0; - int id; - if (((id = fieldBinding.type.id) == T_double) || (id == T_long)) - stackDepth -= 2; - else - stackDepth -= 1; - if (stackDepth > stackMax) - stackMax = stackDepth; - if (classFileOffset + 2 >= bCodeStream.length) { - resizeByteArray(); + int returnTypeSize = 1; + if ((fieldBinding.type.id == T_double) || (fieldBinding.type.id == T_long)) { + returnTypeSize = 2; } - position++; - bCodeStream[classFileOffset++] = OPC_putstatic; - writeUnsignedShort(constantPool.literalIndex(fieldBinding)); + generateFieldAccess( + OPC_putstatic, + returnTypeSize, + fieldBinding.declaringClass.constantPoolName(), + fieldBinding.name, + fieldBinding.type.signature()); } public void record(LocalVariableBinding local) { if (!generateLocalVariableTableAttributes) @@ -4574,15 +5271,14 @@ public void recordPositionsFrom(int startPC, int sourcePos) { if (existingEntryIndex != -1) { // widen existing entry pcToSourceMap[existingEntryIndex] = startPC; - } else { + } else if (insertionIndex < 1 || pcToSourceMap[insertionIndex - 1] != newLine) { // we have to add an entry that won't be sorted. So we sort the pcToSourceMap. System.arraycopy(pcToSourceMap, insertionIndex, pcToSourceMap, insertionIndex + 2, pcToSourceMapSize - insertionIndex); pcToSourceMap[insertionIndex++] = startPC; pcToSourceMap[insertionIndex] = newLine; pcToSourceMapSize += 2; } - } - if (position != lastEntryPC) { // no bytecode since last entry pc + } else if (position != lastEntryPC) { // no bytecode since last entry pc pcToSourceMap[pcToSourceMapSize++] = lastEntryPC; pcToSourceMap[pcToSourceMapSize++] = newLine; } @@ -4630,12 +5326,22 @@ public void recordPositionsFrom(int startPC, int sourcePos) { */ public void registerExceptionHandler(ExceptionLabel anExceptionLabel) { int length; - if (exceptionHandlersNumber >= (length = exceptionHandlers.length)) { + if (exceptionHandlersIndex >= (length = exceptionHandlers.length)) { // resize the exception handlers table System.arraycopy(exceptionHandlers, 0, exceptionHandlers = new ExceptionLabel[length + LABELS_INCREMENT], 0, length); } // no need to resize. So just add the new exception label - exceptionHandlers[exceptionHandlersNumber++] = anExceptionLabel; + exceptionHandlers[exceptionHandlersIndex++] = anExceptionLabel; + exceptionHandlersCounter++; +} +public void removeExceptionHandler(ExceptionLabel exceptionLabel) { + for (int i = 0; i < exceptionHandlersIndex; i++) { + if (exceptionHandlers[i] == exceptionLabel) { + exceptionHandlers[i] = null; + exceptionHandlersCounter--; + return; + } + } } public final void removeNotDefinitelyAssignedVariables(Scope scope, int initStateIndex) { // given some flow info, make sure we did not loose some variables initialization