diff --git a/springloaded/.classpath b/springloaded/.classpath index 720d087..4b125a4 100644 --- a/springloaded/.classpath +++ b/springloaded/.classpath @@ -2,9 +2,9 @@ - - - + + + diff --git a/springloaded/build.gradle b/springloaded/build.gradle index 7198029..73490ae 100644 --- a/springloaded/build.gradle +++ b/springloaded/build.gradle @@ -41,8 +41,8 @@ task wrapper(type: Wrapper) { dependencies { tools 'com.googlecode.jarjar:jarjar:1.3' - compile 'org.ow2.asm:asm:5.0_BETA' - compile 'org.ow2.asm:asm-tree:5.0_BETA' + compile 'org.ow2.asm:asm:5.0.2' + compile 'org.ow2.asm:asm-tree:5.0.2' testCompile 'junit:junit:4.11' diff --git a/springloaded/lib/asm-5.0.2-sources.zip b/springloaded/lib/asm-5.0.2-sources.zip new file mode 100644 index 0000000..f5846d7 Binary files /dev/null and b/springloaded/lib/asm-5.0.2-sources.zip differ diff --git a/springloaded/lib/asm-5.0.2.jar b/springloaded/lib/asm-5.0.2.jar new file mode 100644 index 0000000..d3e6982 Binary files /dev/null and b/springloaded/lib/asm-5.0.2.jar differ diff --git a/springloaded/lib/asm-tree-5.0.2.jar b/springloaded/lib/asm-tree-5.0.2.jar new file mode 100644 index 0000000..be2e45f Binary files /dev/null and b/springloaded/lib/asm-tree-5.0.2.jar differ diff --git a/springloaded/src/main/java/org/springsource/loaded/ClassRenamer.java b/springloaded/src/main/java/org/springsource/loaded/ClassRenamer.java index 921524e..93a2ba2 100644 --- a/springloaded/src/main/java/org/springsource/loaded/ClassRenamer.java +++ b/springloaded/src/main/java/org/springsource/loaded/ClassRenamer.java @@ -271,7 +271,7 @@ public class ClassRenamer { mv.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); } - public void visitMethodInsn(int opcode, String owner, String name, String desc) { + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { if (owner.equals(oldname)) { owner = newname; } else { @@ -282,7 +282,7 @@ public class ClassRenamer { } else { desc = checkIfShouldBeRewritten(desc); } - mv.visitMethodInsn(opcode, owner, name, desc); + mv.visitMethodInsn(opcode, owner, name, desc, itf); } private String checkIfShouldBeRewritten(String desc) { diff --git a/springloaded/src/main/java/org/springsource/loaded/ConstructorCopier.java b/springloaded/src/main/java/org/springsource/loaded/ConstructorCopier.java index bb398c1..b2ea178 100644 --- a/springloaded/src/main/java/org/springsource/loaded/ConstructorCopier.java +++ b/springloaded/src/main/java/org/springsource/loaded/ConstructorCopier.java @@ -67,8 +67,9 @@ class ConstructorCopier extends MethodVisitor implements Constants { super.visitTypeInsn(opcode, type); } + // TODO may need to pay attention itf==true @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, boolean itf) { // If this is an invokespecial, first determine if it is the one of interest (the one calling our super constructor) if (opcode == INVOKESPECIAL && name.charAt(0) == '<') { if (unitializedObjectsCount != 0) { @@ -114,11 +115,11 @@ class ConstructorCopier extends MethodVisitor implements Constants { // no stack is instance then params then instance mv.visitLdcInsn("" + desc); mv.visitMethodInsn(INVOKESPECIAL, typeDescriptor.getSupertypeName(), mDynamicDispatchName, - mDynamicDispatchDescriptor); + mDynamicDispatchDescriptor, false); mv.visitInsn(POP); } else { // it did exist in the original, so there will be parallel constructor - mv.visitMethodInsn(INVOKESPECIAL, typeDescriptor.getSupertypeName(), mInitializerName, desc); + mv.visitMethodInsn(INVOKESPECIAL, typeDescriptor.getSupertypeName(), mInitializerName, desc, false); } } } @@ -134,19 +135,19 @@ class ConstructorCopier extends MethodVisitor implements Constants { if (opcode == INVOKESPECIAL && name.charAt(0) != '<' && owner.equals(classname) && !name.startsWith("r$")) { // leaving the invokespecial alone will cause a verify error String descriptor = Utils.insertExtraParameter(owner, desc); - super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, descriptor); + super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, descriptor, false); } else { boolean done = false; // TODO dup of code in method copier - can we refactor? if (opcode == INVOKESTATIC) { MethodMember mm = typeDescriptor.getByDescriptor(name, desc); if (mm != null && mm.isPrivate()) { - super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, desc); + super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, desc, false); done = true; } } if (!done) { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); } } } diff --git a/springloaded/src/main/java/org/springsource/loaded/DispatcherBuilder.java b/springloaded/src/main/java/org/springsource/loaded/DispatcherBuilder.java index 16a175d..e544e0c 100644 --- a/springloaded/src/main/java/org/springsource/loaded/DispatcherBuilder.java +++ b/springloaded/src/main/java/org/springsource/loaded/DispatcherBuilder.java @@ -91,7 +91,7 @@ public class DispatcherBuilder { MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); mv.visitCode(); mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); @@ -100,7 +100,7 @@ public class DispatcherBuilder { private void generateClinitDispatcher() { MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, mStaticInitializerName, "()V", null, null); mv.visitCode(); - mv.visitMethodInsn(INVOKESTATIC, executorClassName, mStaticInitializerName, "()V"); + mv.visitMethodInsn(INVOKESTATIC, executorClassName, mStaticInitializerName, "()V", false); mv.visitInsn(RETURN); mv.visitMaxs(1, 1); mv.visitEnd(); @@ -175,7 +175,7 @@ public class DispatcherBuilder { // 2. Load the input name+descriptor and compare it with this method: mv.visitVarInsn(ALOAD, 3); mv.visitLdcInsn(nameWithDescriptor); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); Label label = new Label(); mv.visitJumpInsn(IFEQ, label); // means if false @@ -196,7 +196,7 @@ public class DispatcherBuilder { Utils.generateInstructionsToUnpackArrayAccordingToDescriptor(mv, method.descriptor, 1); ReturnType returnType = Utils.getReturnTypeDescriptor(method.descriptor); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, executorClassName, method.name, callDescriptor); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, executorClassName, method.name, callDescriptor, false); if (returnType.isVoid()) { mv.visitInsn(ACONST_NULL); } else if (returnType.isPrimitive()) { @@ -212,7 +212,7 @@ public class DispatcherBuilder { // if (nameAndDescriptor.equals(xxx)) { mv.visitVarInsn(ALOAD, indexNameAndDescriptor); mv.visitLdcInsn(nameWithDescriptor); - mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z"); + mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "equals", "(Ljava/lang/Object;)Z", false); Label label = new Label(); mv.visitJumpInsn(IFEQ, label); // means if false @@ -230,7 +230,7 @@ public class DispatcherBuilder { Utils.generateInstructionsToUnpackArrayAccordingToDescriptor(mv, ctor.descriptor, 1); // ReturnType returnType = Utils.getReturnTypeDescriptor(method.descriptor); - mv.visitMethodInsn(Opcodes.INVOKESTATIC, executorClassName, "___init___", callDescriptor); + mv.visitMethodInsn(Opcodes.INVOKESTATIC, executorClassName, "___init___", callDescriptor, false); // if (returnType.isVoid()) { mv.visitInsn(ACONST_NULL); // } else if (returnType.isPrimitive()) { @@ -254,7 +254,7 @@ public class DispatcherBuilder { // getDispatcher will give us the dispatcher for the supertype mv.visitFieldInsn(Opcodes.GETSTATIC, slashedSupertypeName, fReloadableTypeFieldName, lReloadableType); mv.visitMethodInsn(INVOKEVIRTUAL, tReloadableType, "getDispatcher", - "()Lorg/springsource/loaded/__DynamicallyDispatchable;"); + "()Lorg/springsource/loaded/__DynamicallyDispatchable;", false); // alternative 2: find the right dispatcher - i.e. who in the super hierarchy provides that nameAndDescriptor @@ -262,7 +262,7 @@ public class DispatcherBuilder { mv.visitVarInsn(ALOAD, indexArgs); mv.visitVarInsn(ALOAD, indexTarget); mv.visitVarInsn(ALOAD, indexNameAndDescriptor); - mv.visitMethodInsn(INVOKEINTERFACE, tDynamicallyDispatchable, mDynamicDispatchName, mDynamicDispatchDescriptor); + mv.visitMethodInsn(INVOKEINTERFACE, tDynamicallyDispatchable, mDynamicDispatchName, mDynamicDispatchDescriptor, false); mv.visitInsn(ARETURN); // mv.visitTypeInsn(NEW, "java/lang/IllegalStateException"); @@ -313,7 +313,7 @@ public class DispatcherBuilder { int params = Utils.getParameterCount(descriptor); String callDescriptor = isStatic ? originalDescriptor : descriptor; Utils.createLoadsBasedOnDescriptor(mv, callDescriptor, isStatic ? 2 : 1); - mv.visitMethodInsn(INVOKESTATIC, executorClassName, name, callDescriptor); + mv.visitMethodInsn(INVOKESTATIC, executorClassName, name, callDescriptor, false); Utils.addCorrectReturnInstruction(mv, returnTypeDescriptor, false); mv.visitMaxs(params, params + 1); mv.visitEnd(); diff --git a/springloaded/src/main/java/org/springsource/loaded/MethodCopier.java b/springloaded/src/main/java/org/springsource/loaded/MethodCopier.java index 6505103..9f94034 100644 --- a/springloaded/src/main/java/org/springsource/loaded/MethodCopier.java +++ b/springloaded/src/main/java/org/springsource/loaded/MethodCopier.java @@ -108,16 +108,16 @@ class MethodCopier extends MethodVisitor implements Constants { if (fm != null) { switch (opcode) { case GETFIELD: - mv.visitMethodInsn(INVOKEVIRTUAL, classname, Utils.getProtectedFieldGetterName(name), "()" + desc); + mv.visitMethodInsn(INVOKEVIRTUAL, classname, Utils.getProtectedFieldGetterName(name), "()" + desc, false); return; case PUTFIELD: - mv.visitMethodInsn(INVOKEVIRTUAL, classname, Utils.getProtectedFieldSetterName(name), "(" + desc + ")V"); + mv.visitMethodInsn(INVOKEVIRTUAL, classname, Utils.getProtectedFieldSetterName(name), "(" + desc + ")V", false); return; case GETSTATIC: - mv.visitMethodInsn(INVOKESTATIC, classname, Utils.getProtectedFieldGetterName(name), "()" + desc); + mv.visitMethodInsn(INVOKESTATIC, classname, Utils.getProtectedFieldGetterName(name), "()" + desc, false); return; case PUTSTATIC: - mv.visitMethodInsn(INVOKESTATIC, classname, Utils.getProtectedFieldSetterName(name), "(" + desc + ")V"); + mv.visitMethodInsn(INVOKESTATIC, classname, Utils.getProtectedFieldSetterName(name), "(" + desc + ")V", false); return; } } @@ -125,8 +125,9 @@ class MethodCopier extends MethodVisitor implements Constants { super.visitFieldInsn(opcode, owner, name, desc); } + // TODO maybe do something if 'itf==true' @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, boolean itf) { // Is it a private method call? // TODO r$ check here because we use invokespecial to avoid virtual dispatch on field changes... if (opcode == INVOKESPECIAL && name.charAt(0) != '<' && !name.startsWith("r$")) { @@ -134,7 +135,7 @@ class MethodCopier extends MethodVisitor implements Constants { // private method call // leaving the invokespecial alone will cause a verify error String descriptor = Utils.insertExtraParameter(owner, desc); - super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, descriptor); + super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, descriptor, false); return; } else { // super call @@ -146,9 +147,9 @@ class MethodCopier extends MethodVisitor implements Constants { MethodMember target = supertypeDescriptor.getByNameAndDescriptor(name+desc); if (target!=null && target.isProtected()) { // A null target means that method is not in the supertype, so didn't get a superdispatcher - super.visitMethodInsn(INVOKESPECIAL,classname,name+methodSuffixSuperDispatcher,desc); + super.visitMethodInsn(INVOKESPECIAL,classname,name+methodSuffixSuperDispatcher,desc, false); } else { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); } return; } @@ -158,12 +159,12 @@ class MethodCopier extends MethodVisitor implements Constants { if (opcode == INVOKESTATIC) { MethodMember mm = typeDescriptor.getByDescriptor(name, desc); if (mm != null && mm.isPrivate()) { - super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, desc); + super.visitMethodInsn(INVOKESTATIC, Utils.getExecutorName(classname, suffix), name, desc, false); done = true; } } if (!done) { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); } } diff --git a/springloaded/src/main/java/org/springsource/loaded/MethodInvokerRewriter.java b/springloaded/src/main/java/org/springsource/loaded/MethodInvokerRewriter.java index edbef25..09a55ee 100644 --- a/springloaded/src/main/java/org/springsource/loaded/MethodInvokerRewriter.java +++ b/springloaded/src/main/java/org/springsource/loaded/MethodInvokerRewriter.java @@ -818,7 +818,7 @@ public class MethodInvokerRewriter { // Make a call to check if this field operation must be intercepted: mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name); - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mInstanceFieldInterceptionRequired, "(ILjava/lang/String;)Z"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mInstanceFieldInterceptionRequired, "(ILjava/lang/String;)Z", false); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); // IF (false) GOTO l1 Utils.insertBoxInsns(mv, desc); // box the value if necessary @@ -827,7 +827,7 @@ public class MethodInvokerRewriter { // now stack is: FieldAccessor|newValue|target mv.visitLdcInsn(name); mv.visitMethodInsn(INVOKESPECIAL, owner, mInstanceFieldSetterName, - "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)V"); + "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)V", false); Label l2 = new Label(); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l1); // Did not need intercepting, do what you were going to do: @@ -847,13 +847,13 @@ public class MethodInvokerRewriter { // intercepted mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name); - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mInstanceFieldInterceptionRequired, "(ILjava/lang/String;)Z"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mInstanceFieldInterceptionRequired, "(ILjava/lang/String;)Z", false); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); // IF (false) GOTO l1 mv.visitInsn(DUP); mv.visitLdcInsn(name); mv.visitMethodInsn(INVOKESPECIAL, owner, mInstanceFieldGetterName, - "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;"); + "(Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;", false); if (desc.length() != 1) { if (!desc.equals(jlObject)) { mv.visitTypeInsn(CHECKCAST, toDescriptor(desc)); @@ -874,13 +874,13 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); // Make a call to check if this field operation must be intercepted: mv.visitLdcInsn(name); - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mStaticFieldInterceptionRequired, "(ILjava/lang/String;)Z"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mStaticFieldInterceptionRequired, "(ILjava/lang/String;)Z", false); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); // IF (false) GOTO l1 // top of heap will be the new value Utils.insertBoxInsns(mv, desc); mv.visitLdcInsn(name); - mv.visitMethodInsn(INVOKESTATIC, owner, mStaticFieldSetterName, "(Ljava/lang/Object;Ljava/lang/String;)V"); + mv.visitMethodInsn(INVOKESTATIC, owner, mStaticFieldSetterName, "(Ljava/lang/Object;Ljava/lang/String;)V", false); Label l2 = new Label(); mv.visitJumpInsn(GOTO, l2); mv.visitLabel(l1); @@ -893,12 +893,12 @@ public class MethodInvokerRewriter { // Make a call to check if this field operation must be intercepted: mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name); - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mStaticFieldInterceptionRequired, "(ILjava/lang/String;)Z"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mStaticFieldInterceptionRequired, "(ILjava/lang/String;)Z", false); Label l1 = new Label(); mv.visitJumpInsn(IFEQ, l1); // IF (false) GOTO l1 // top of heap will be the new value mv.visitLdcInsn(name); - mv.visitMethodInsn(INVOKESTATIC, owner, mStaticFieldGetterName, "(Ljava/lang/String;)Ljava/lang/Object;"); + mv.visitMethodInsn(INVOKESTATIC, owner, mStaticFieldGetterName, "(Ljava/lang/String;)Ljava/lang/Object;", false); if (desc.length() != 1) { if (!desc.equals(jlObject)) { mv.visitTypeInsn(CHECKCAST, toDescriptor(desc)); @@ -1014,7 +1014,7 @@ public class MethodInvokerRewriter { // do more hoop jumping. // Check on reloading having happened - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeDynamicName, "()Ljava/lang/Object;"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeDynamicName, "()Ljava/lang/Object;", false); // mv.visitInsn(DUP); @@ -1029,10 +1029,10 @@ public class MethodInvokerRewriter { // Method java/lang/invoke/MethodHandles.lookup:()Ljava/lang/invoke/MethodHandles$Lookup; mv.visitLdcInsn(typeRegistry.getId()); mv.visitLdcInsn(classId); - mv.visitMethodInsn(INVOKESTATIC,"java/lang/invoke/MethodHandles","lookup","()Ljava/lang/invoke/MethodHandles$Lookup;"); + mv.visitMethodInsn(INVOKESTATIC,"java/lang/invoke/MethodHandles","lookup","()Ljava/lang/invoke/MethodHandles$Lookup;", false); mv.visitLdcInsn(name+desc); // Ljava/lang/String; mv.visitLdcInsn(bsmReferenceId); // I - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mPerformInvokeDynamicName, "([Ljava/lang/Object;IILjava/lang/Object;Ljava/lang/String;I)Ljava/lang/Object;"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mPerformInvokeDynamicName, "([Ljava/lang/Object;IILjava/lang/Object;Ljava/lang/String;I)Ljava/lang/Object;", false); Label gotolabel = new Label(); mv.visitJumpInsn(GOTO, gotolabel); @@ -1049,7 +1049,7 @@ public class MethodInvokerRewriter { } @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { if (GlobalConfiguration.interceptReflection && rewriteReflectiveCall(opcode, owner, name, desc)) { return; } @@ -1057,7 +1057,7 @@ public class MethodInvokerRewriter { unitializedObjectsCount--; } if (name.equals("$getCallSiteArray")) { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); return; } // TODO [cglib optimizations] could recognize things that dont @@ -1069,7 +1069,7 @@ public class MethodInvokerRewriter { boolean isReloadable = typeRegistry != null && (owner.equals(slashedclassname) ? thisClassIsReloadable : typeRegistry.isReloadableTypeName(owner)); if (!isReloadable) { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); return; } rewroteOtherKindOfOperation = true; @@ -1078,13 +1078,13 @@ public class MethodInvokerRewriter { // boolean isVoidReturn = returnType.isVoid(); int classId = typeRegistry.getTypeIdFor(owner, true); if (opcode == INVOKESTATIC) { - rewriteINVOKESTATIC(opcode, owner, name, desc, hasParams, returnType, classId); + rewriteINVOKESTATIC(opcode, owner, name, desc, hasParams, returnType, classId, itf); } else if (opcode == INVOKEINTERFACE) { - rewriteINVOKEINTERFACE(opcode, owner, name, desc, hasParams, returnType, classId); + rewriteINVOKEINTERFACE(opcode, owner, name, desc, hasParams, returnType, classId, itf); } else if (opcode == INVOKEVIRTUAL) { - rewriteINVOKEVIRTUAL(opcode, owner, name, desc, hasParams, returnType, classId); + rewriteINVOKEVIRTUAL(opcode, owner, name, desc, hasParams, returnType, classId, itf); } else if (opcode == INVOKESPECIAL) { - rewriteINVOKESPECIAL(opcode, owner, name, desc, hasParams, returnType, classId); + rewriteINVOKESPECIAL(opcode, owner, name, desc, hasParams, returnType, classId, itf); } else { Utils.logAndThrow(log, "Failed to rewrite instruction " + Utils.toOpcodeString(opcode) + " in method " + this.methodname); @@ -1123,7 +1123,7 @@ public class MethodInvokerRewriter { * Rewrite an INVOKESTATIC instruction. */ private void rewriteINVOKESTATIC(final int opcode, final String owner, final String name, final String desc, - boolean hasParams, ReturnType returnType, int classId) { + boolean hasParams, ReturnType returnType, int classId, boolean itf) { // 1. call istcheck(classId|methodId, // methodName+methodDescriptor) // If it returns 'null' then nothing has changed and the code @@ -1133,7 +1133,7 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name + desc); mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeStaticName, - "(ILjava/lang/String;)Ljava/lang/Object;"); + "(ILjava/lang/String;)Ljava/lang/Object;", false); // 2. preserve a copy of the return value (new target) mv.visitInsn(DUP); @@ -1168,7 +1168,7 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(name + desc); // 7. calling __execute(params array,this,name+desc) - mv.visitMethodInsn(INVOKEINTERFACE, Utils.getInterfaceName(owner), mDynamicDispatchName, mDynamicDispatchDescriptor); + mv.visitMethodInsn(INVOKEINTERFACE, Utils.getInterfaceName(owner), mDynamicDispatchName, mDynamicDispatchDescriptor, true); insertAppropriateReturn(returnType); // 8. jump over the original call @@ -1177,7 +1177,7 @@ public class MethodInvokerRewriter { // 9. do what we were going to do mv.visitLabel(l1); mv.visitInsn(POP); - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); mv.visitLabel(gotolabel); } @@ -1207,11 +1207,11 @@ public class MethodInvokerRewriter { * */ private void rewriteINVOKEINTERFACE(final int opcode, final String owner, final String name, final String desc, - boolean hasParams, ReturnType returnType, int classId) { + boolean hasParams, ReturnType returnType, int classId, final boolean itf) { // 1. call 'boolean iicheck(classId|methodId, methodName+methodDescriptor)' to see if this needs interception mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name + desc); - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeInterfaceName, "(ILjava/lang/String;)Z"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeInterfaceName, "(ILjava/lang/String;)Z", false); // 3. if false, do what was going to be done anyway Label l1 = new Label(); @@ -1239,11 +1239,11 @@ public class MethodInvokerRewriter { if (GlobalConfiguration.isJava18orHigher) { // if the target is a generated lambda callsite object then calling __execute isn't going to work as those // types don't have the method in them! - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, "iiIntercept", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, "iiIntercept", "(Ljava/lang/Object;[Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/String;)Ljava/lang/Object;", false); } else { // calling __execute(params array, this, name+desc) - mv.visitMethodInsn(INVOKEINTERFACE, owner, mDynamicDispatchName, mDynamicDispatchDescriptor); + mv.visitMethodInsn(INVOKEINTERFACE, owner, mDynamicDispatchName, mDynamicDispatchDescriptor, true); } insertAppropriateReturn(returnType); @@ -1251,17 +1251,17 @@ public class MethodInvokerRewriter { mv.visitJumpInsn(GOTO, gotolabel); mv.visitLabel(l1); // do what we were going to do: - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, true); mv.visitLabel(gotolabel); } private void rewriteINVOKEVIRTUAL(final int opcode, final String owner, final String name, final String desc, - boolean hasParams, ReturnType returnType, int classId) { + boolean hasParams, ReturnType returnType, int classId, final boolean itf) { // 1. call icheck(classId|methodId, methodName+methodDescriptor) // to see if this needs interception mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name + desc); - mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeVirtualName, "(ILjava/lang/String;)Z"); + mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeVirtualName, "(ILjava/lang/String;)Z", false); // Return value is the extracted interface to call if there is a // change and it can't be called directly @@ -1299,7 +1299,7 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(name + desc); // calling __execute(params array,this,name+desc) - mv.visitMethodInsn(INVOKEVIRTUAL, owner, mDynamicDispatchName, mDynamicDispatchDescriptor); + mv.visitMethodInsn(INVOKEVIRTUAL, owner, mDynamicDispatchName, mDynamicDispatchDescriptor, itf); insertAppropriateReturn(returnType); Label gotolabel = new Label(); @@ -1308,7 +1308,7 @@ public class MethodInvokerRewriter { // mv.visitInsn(POP); // Here is where we end up if the test for changes failed (ie. // there were no changes - just 'do what you were going to do' - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); mv.visitLabel(gotolabel); } @@ -1320,14 +1320,14 @@ public class MethodInvokerRewriter { * package up our parameters and invoke it. */ private void rewriteINVOKESPECIAL(final int opcode, final String owner, final String name, final String desc, - boolean hasParams, ReturnType returnType, int classId) { + boolean hasParams, ReturnType returnType, int classId, final boolean itf) { if (unitializedObjectsCount == -1 && name.charAt(0) == '<') { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); return; } if (!name.equals("") && owner.equals(slashedclassname)) { // being used to invoke a private method - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); // the executor builder will sort it out return; } @@ -1336,7 +1336,7 @@ public class MethodInvokerRewriter { // constructor if (isEnum && isClinitOrEnumInit && fieldcount > GlobalConfiguration.enumLimit && owner.equals(slashedclassname)) { - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); return; } @@ -1345,7 +1345,7 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(desc); mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForConstructorName, - "(ILjava/lang/String;)Ljava/lang/Object;"); + "(ILjava/lang/String;)Ljava/lang/Object;", false); mv.visitInsn(DUP); // 3. Was it null? @@ -1396,7 +1396,7 @@ public class MethodInvokerRewriter { Utils.insertUnboxInsns(mv, 'I', true); mv.visitInsn(ACONST_NULL); - mv.visitMethodInsn(INVOKESPECIAL, owner, "", "(Ljava/lang/String;ILorg/springsource/loaded/C;)V"); + mv.visitMethodInsn(INVOKESPECIAL, owner, "", "(Ljava/lang/String;ILorg/springsource/loaded/C;)V", itf); } else if (owner.contains("_closure")) { // TODO need more robust way to identify when target is a closure? mv.visitInsn(SWAP); // now params array on top instance underneath mv.visitInsn(DUP_X1); // give us an array instance to retrieve 1 from @@ -1408,10 +1408,10 @@ public class MethodInvokerRewriter { mv.visitInsn(AALOAD); mv.visitInsn(ACONST_NULL); mv.visitMethodInsn(INVOKESPECIAL, owner, "", - "(Ljava/lang/Object;Ljava/lang/Object;Lorg/springsource/loaded/C;)V"); + "(Ljava/lang/Object;Ljava/lang/Object;Lorg/springsource/loaded/C;)V", itf); } else { mv.visitInsn(ACONST_NULL); - mv.visitMethodInsn(INVOKESPECIAL, owner, "", "(Lorg/springsource/loaded/C;)V"); + mv.visitMethodInsn(INVOKESPECIAL, owner, "", "(Lorg/springsource/loaded/C;)V", itf); } // stack is now an instance then the params @@ -1428,7 +1428,7 @@ public class MethodInvokerRewriter { // stack is now the two instances mv.visitInsn(DUP); mv.visitInsn(ACONST_NULL); - mv.visitMethodInsn(INVOKESPECIAL, owner, "", "(Lorg/springsource/loaded/C;)V"); + mv.visitMethodInsn(INVOKESPECIAL, owner, "", "(Lorg/springsource/loaded/C;)V", itf); // stack is now an instance mv.visitVarInsn(ALOAD, max + 1); // stack is now an instance then the dispatcher instance @@ -1440,7 +1440,7 @@ public class MethodInvokerRewriter { // stack is now the dispatcher instance, null, the instance and the name+desc! } mv.visitMethodInsn(INVOKEINTERFACE, "org/springsource/loaded/__DynamicallyDispatchable", mDynamicDispatchName, - mDynamicDispatchDescriptor); + mDynamicDispatchDescriptor, true); mv.visitInsn(POP); // mv.visitMethodInsn(INVOKESPECIAL, "ctors/Callee", "", "()V"); @@ -1457,7 +1457,7 @@ public class MethodInvokerRewriter { mv.visitJumpInsn(GOTO, gotolabel); mv.visitLabel(l1); mv.visitInsn(POP); - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); mv.visitLabel(gotolabel); } else { @@ -1466,7 +1466,7 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(Utils.toCombined(typeRegistry.getId(), classId)); mv.visitLdcInsn(name + desc); mv.visitMethodInsn(INVOKESTATIC, tRegistryType, mChangedForInvokeSpecialName, - descriptorChangedForInvokeSpecialName); + descriptorChangedForInvokeSpecialName, false); // Return value is the dispatcher instance to call if there is a // change such that it can't be called directly - the method we called @@ -1506,14 +1506,14 @@ public class MethodInvokerRewriter { mv.visitLdcInsn(name + desc); mv.visitMethodInsn(INVOKEINTERFACE, "org/springsource/loaded/__DynamicallyDispatchable", mDynamicDispatchName, - mDynamicDispatchDescriptor); + mDynamicDispatchDescriptor, true); insertAppropriateReturn(returnType); Label gotolabel = new Label(); mv.visitJumpInsn(GOTO, gotolabel); mv.visitLabel(l1); mv.visitInsn(POP); - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); mv.visitLabel(gotolabel); } } diff --git a/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionInvestigator.java b/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionInvestigator.java index 7684c89..c4be72b 100644 --- a/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionInvestigator.java +++ b/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionInvestigator.java @@ -101,14 +101,14 @@ public class SystemClassReflectionInvestigator { } @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { if (!GlobalConfiguration.interceptReflection || rewriteReflectiveCall(opcode, owner, name, desc)) { return; } if (opcode == INVOKESPECIAL) { unitializedObjectsCount--; } - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); } /** diff --git a/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionRewriter.java b/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionRewriter.java index 7f9eaf1..cc5fae0 100644 --- a/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionRewriter.java +++ b/springloaded/src/main/java/org/springsource/loaded/SystemClassReflectionRewriter.java @@ -269,7 +269,7 @@ public class SystemClassReflectionRewriter { } @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { if (!GlobalConfiguration.interceptReflection || rewriteReflectiveCall(opcode, owner, name, desc)) { return; } @@ -309,7 +309,7 @@ public class SystemClassReflectionRewriter { ////// } // } // } - super.visitMethodInsn(opcode, owner, name, desc); + super.visitMethodInsn(opcode, owner, name, desc, itf); } /** @@ -338,57 +338,57 @@ public class SystemClassReflectionRewriter { if (name.equals("getDeclaredFields")) { // stack on arrival: bits |= JLC_GETDECLAREDFIELDS; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdfs, jlcgdfsDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdfs, jlcgdfsDescriptor, false); return true; } else if (name.equals("getDeclaredField")) { // stack on arrival: bits |= JLC_GETDECLAREDFIELD; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdf, jlcgdfDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdf, jlcgdfDescriptor, false); return true; } else if (name.equals("getField")) { // stack on arrival: bits |= JLC_GETFIELD; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgf, jlcgfDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgf, jlcgfDescriptor, false); return true; } else if (name.equals("getDeclaredMethods")) { // stack on arrival: bits |= JLC_GETDECLAREDMETHODS; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdms, jlcgdmsDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdms, jlcgdmsDescriptor, false); return true; } else if (name.equals("getDeclaredMethod")) { // stack on arrival: bits |= JLC_GETDECLAREDMETHOD; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdm, jlcgdmDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdm, jlcgdmDescriptor, false); return true; } else if (name.equals("getMethod")) { // stack on arrival: bits |= JLC_GETMETHOD; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgm, jlcgmDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgm, jlcgmDescriptor, false); return true; } else if (name.equals("getDeclaredConstructor")) { // stack on arrival: bits |= JLC_GETDECLAREDCONSTRUCTOR; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdc, jlcgdcDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgdc, jlcgdcDescriptor, false); return true; } else if (name.equals("getDeclaredConstructors")) { // stack on arrival: bits |= JLC_GETDECLAREDCONSTRUCTORS; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcGetDeclaredConstructorsMember,jlcGetDeclaredConstructorsDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcGetDeclaredConstructorsMember,jlcGetDeclaredConstructorsDescriptor, false); return true; } else if (name.equals("getConstructor")) { // stack on arrival: bits |= JLC_GETCONSTRUCTOR; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgc, jlcgcDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgc, jlcgcDescriptor, false); return true; } else if (name.equals("getModifiers")) { // stack on arrival: bits |= JLC_GETMODIFIERS; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgmods, jlcgmodsDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgmods, jlcgmodsDescriptor, false); return true; } else if (name.equals("getMethods")) { // stack on arrival: bits |= JLC_GETMETHODS; - mv.visitMethodInsn(INVOKESTATIC, classname, jlcgms, jlcgmsDescriptor); + mv.visitMethodInsn(INVOKESTATIC, classname, jlcgms, jlcgmsDescriptor, false); return true; } else if (name.equals("newInstance")) { // TODO determine if this actually needs rewriting? Just catching in this if clause to avoid the message diff --git a/springloaded/src/main/java/org/springsource/loaded/TypeRewriter.java b/springloaded/src/main/java/org/springsource/loaded/TypeRewriter.java index f8a7bd0..c39b4e9 100644 --- a/springloaded/src/main/java/org/springsource/loaded/TypeRewriter.java +++ b/springloaded/src/main/java/org/springsource/loaded/TypeRewriter.java @@ -1019,8 +1019,8 @@ public class TypeRewriter implements Constants { } @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - super.visitMethodInsn(opcode, owner, name, desc); + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { + super.visitMethodInsn(opcode, owner, name, desc, itf); if (opcode == INVOKESPECIAL) { unitializedObjectsCount--; } @@ -1037,7 +1037,7 @@ public class TypeRewriter implements Constants { mv.visitVarInsn(ALOAD, 0); mv.visitFieldInsn(Opcodes.GETSTATIC, slashedname, fReloadableTypeFieldName, lReloadableType); mv.visitMethodInsn(INVOKESPECIAL, tInstanceStateManager, "", - "(Ljava/lang/Object;Lorg/springsource/loaded/ReloadableType;)V"); + "(Ljava/lang/Object;Lorg/springsource/loaded/ReloadableType;)V", false); // mv.visitMethodInsn(INVOKESPECIAL, tInstanceStateManager, "", "(Ljava/lang/Object;)V"); mv.visitFieldInsn(PUTFIELD, slashedname, fInstanceFieldsName, lInstanceStateManager); mv.visitLabel(l1); diff --git a/springloaded/src/main/java/org/springsource/loaded/agent/CglibPluginCapturing.java b/springloaded/src/main/java/org/springsource/loaded/agent/CglibPluginCapturing.java index 659f7df..d3182c4 100644 --- a/springloaded/src/main/java/org/springsource/loaded/agent/CglibPluginCapturing.java +++ b/springloaded/src/main/java/org/springsource/loaded/agent/CglibPluginCapturing.java @@ -88,8 +88,8 @@ public class CglibPluginCapturing extends ClassVisitor implements Constants { * this type so that we can remember the generator used (and drive it again later when the related type is reloaded). */ @Override - public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { - super.visitMethodInsn(opcode, owner, name, desc); + public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc, final boolean itf) { + super.visitMethodInsn(opcode, owner, name, desc, itf); if (name.equals("generate")) { // Code that calls generate: // ALOAD 0 @@ -101,7 +101,7 @@ public class CglibPluginCapturing extends ClassVisitor implements Constants { "L"+prefix+"/cglib/core/GeneratorStrategy;"); mv.visitVarInsn(ALOAD, 0); // AbstractClassGenerator instance mv.visitMethodInsn(INVOKESTATIC, "org/springsource/loaded/agent/CglibPluginCapturing", "record", - "(Ljava/lang/Object;Ljava/lang/Object;)V");//Lnet/sf/cglib/core/GeneratorStrategy;Lnet/sf/cglib/core/AbstractClassGenerator);"); + "(Ljava/lang/Object;Ljava/lang/Object;)V", false);//Lnet/sf/cglib/core/GeneratorStrategy;Lnet/sf/cglib/core/AbstractClassGenerator);"); } } diff --git a/springloaded/src/main/java/org/springsource/loaded/agent/ClassVisitingConstructorAppender.java b/springloaded/src/main/java/org/springsource/loaded/agent/ClassVisitingConstructorAppender.java index 5ebf0ab..eba9f88 100644 --- a/springloaded/src/main/java/org/springsource/loaded/agent/ClassVisitingConstructorAppender.java +++ b/springloaded/src/main/java/org/springsource/loaded/agent/ClassVisitingConstructorAppender.java @@ -72,7 +72,7 @@ public class ClassVisitingConstructorAppender extends ClassVisitor implements Co public void visitInsn(int opcode) { if (opcode == RETURN) { mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESTATIC, calleeOwner, calleeName, "(Ljava/lang/Object;)V"); + mv.visitMethodInsn(INVOKESTATIC, calleeOwner, calleeName, "(Ljava/lang/Object;)V", false); } super.visitInsn(opcode); } diff --git a/springloaded/src/main/java/org/springsource/loaded/agent/ModifyDefineInClassLoaderForClassArtifactsType.java b/springloaded/src/main/java/org/springsource/loaded/agent/ModifyDefineInClassLoaderForClassArtifactsType.java index 36e6548..288b1ff 100644 --- a/springloaded/src/main/java/org/springsource/loaded/agent/ModifyDefineInClassLoaderForClassArtifactsType.java +++ b/springloaded/src/main/java/org/springsource/loaded/agent/ModifyDefineInClassLoaderForClassArtifactsType.java @@ -61,7 +61,7 @@ public class ModifyDefineInClassLoaderForClassArtifactsType extends ClassVisitor mv.visitVarInsn(ALOAD, 1); // String name mv.visitVarInsn(ALOAD, 2); // byte[] bytes mv.visitMethodInsn(INVOKESTATIC, "org/springsource/loaded/agent/ModifyDefineInClassLoaderForClassArtifactsType", - "modify", "(Ljava/lang/ClassLoader;Ljava/lang/String;[B)[B"); + "modify", "(Ljava/lang/ClassLoader;Ljava/lang/String;[B)[B", false); mv.visitVarInsn(ASTORE, 2); } diff --git a/springloaded/src/main/java/org/springsource/loaded/pluginhelpers/EmptyCtor.java b/springloaded/src/main/java/org/springsource/loaded/pluginhelpers/EmptyCtor.java index 2bd2606..be077e0 100644 --- a/springloaded/src/main/java/org/springsource/loaded/pluginhelpers/EmptyCtor.java +++ b/springloaded/src/main/java/org/springsource/loaded/pluginhelpers/EmptyCtor.java @@ -127,6 +127,10 @@ public class EmptyCtor extends ClassVisitor implements Constants { public void visitMethodInsn(int opcode, String owner, String name, String desc) { } + + public void visitMethodInsn(int opcode, String owner, String name, + String desc, boolean itf) { + } public void visitJumpInsn(int opcode, Label label) { } @@ -164,7 +168,7 @@ public class EmptyCtor extends ClassVisitor implements Constants { public void visitEnd() { mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V"); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); mv.visitInsn(RETURN); } diff --git a/springloaded/src/main/java/org/springsource/loaded/test/infra/MethodPrinter.java b/springloaded/src/main/java/org/springsource/loaded/test/infra/MethodPrinter.java index 27ec6ed..1ed68a0 100644 --- a/springloaded/src/main/java/org/springsource/loaded/test/infra/MethodPrinter.java +++ b/springloaded/src/main/java/org/springsource/loaded/test/infra/MethodPrinter.java @@ -64,7 +64,8 @@ public class MethodPrinter extends MethodVisitor implements Opcodes { return "#"+bsm.getTag()+" "+bsm.getOwner()+"."+bsm.getName()+bsm.getDesc(); } - public void visitMethodInsn(int opcode, String owner, String name, String desc) { + // TODO include 'itf' flag in output (maybe only if true) + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { if (opcode == Opcodes.INVOKESTATIC) { to.println(" INVOKESTATIC " + owner + "." + name + desc); } else if (opcode == Opcodes.INVOKESPECIAL) { diff --git a/springloaded/src/test/java/org/springsource/loaded/test/ReloadingJVM.java b/springloaded/src/test/java/org/springsource/loaded/test/ReloadingJVM.java index 88576d5..f270e62 100644 --- a/springloaded/src/test/java/org/springsource/loaded/test/ReloadingJVM.java +++ b/springloaded/src/test/java/org/springsource/loaded/test/ReloadingJVM.java @@ -92,6 +92,7 @@ public class ReloadingJVM { System.out.println("java.home="+System.getProperty("java.home")); } process = Runtime.getRuntime().exec( + // Run on my Java6 // "/System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home"+ System.getProperty("java.home")+ "/bin/java -noverify -javaagent:" + agentJarLocation + " -cp " + javaclasspath + " " + AGENT_OPTION_STRING + diff --git a/springloaded/src/test/java/org/springsource/loaded/test/infra/FakeMethodVisitor.java b/springloaded/src/test/java/org/springsource/loaded/test/infra/FakeMethodVisitor.java index effd0b7..270b4d2 100644 --- a/springloaded/src/test/java/org/springsource/loaded/test/infra/FakeMethodVisitor.java +++ b/springloaded/src/test/java/org/springsource/loaded/test/infra/FakeMethodVisitor.java @@ -98,7 +98,7 @@ public class FakeMethodVisitor extends MethodVisitor implements Constants { public void visitMaxs(int maxStack, int maxLocals) { } - public void visitMethodInsn(int opcode, String owner, String name, String desc) { + public void visitMethodInsn(int opcode, String owner, String name, String desc, boolean itf) { events.append("visitMethodInsn(" + Utils.toOpcodeString(opcode) + "," + owner + "," + name + "," + desc + ") "); } diff --git a/testdata-java8/.classpath b/testdata-java8/.classpath index 7461090..2ff84d5 100644 --- a/testdata-java8/.classpath +++ b/testdata-java8/.classpath @@ -1,6 +1,6 @@ - + diff --git a/testdata-java8/.settings/org.eclipse.jdt.core.prefs b/testdata-java8/.settings/org.eclipse.jdt.core.prefs index 7341ab1..3a21537 100644 --- a/testdata-java8/.settings/org.eclipse.jdt.core.prefs +++ b/testdata-java8/.settings/org.eclipse.jdt.core.prefs @@ -1,11 +1,11 @@ eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.compliance=1.7 +org.eclipse.jdt.core.compiler.compliance=1.8 org.eclipse.jdt.core.compiler.debug.lineNumber=generate org.eclipse.jdt.core.compiler.debug.localVariable=generate org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.source=1.7 +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/testdata/.classpath b/testdata/.classpath index 0fb1905..ab68a84 100644 --- a/testdata/.classpath +++ b/testdata/.classpath @@ -5,6 +5,6 @@ - + diff --git a/testdata/.settings/org.eclipse.jdt.core.prefs b/testdata/.settings/org.eclipse.jdt.core.prefs index 5426d5a..8000cd6 100644 --- a/testdata/.settings/org.eclipse.jdt.core.prefs +++ b/testdata/.settings/org.eclipse.jdt.core.prefs @@ -1,13 +1,11 @@ -# -#Wed Jan 22 08:50:23 PST 2014 -org.eclipse.jdt.core.compiler.debug.localVariable=generate -org.eclipse.jdt.core.compiler.compliance=1.6 -org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve -org.eclipse.jdt.core.compiler.debug.sourceFile=generate -org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 -org.eclipse.jdt.core.compiler.problem.enumIdentifier=error -org.eclipse.jdt.core.compiler.debug.lineNumber=generate eclipse.preferences.version=1 org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled -org.eclipse.jdt.core.compiler.source=1.6 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/testdata/src/main/java/github10/Code.java b/testdata/src/main/java/github10/Code.java new file mode 100644 index 0000000..6a61c42 --- /dev/null +++ b/testdata/src/main/java/github10/Code.java @@ -0,0 +1,5 @@ +package github10; + +public class Code { + +} diff --git a/testdata/src/main/java/remote/Serialize.java b/testdata/src/main/java/remote/Serialize.java index 3ff2e50..e4c6155 100644 --- a/testdata/src/main/java/remote/Serialize.java +++ b/testdata/src/main/java/remote/Serialize.java @@ -159,6 +159,9 @@ public class Serialize { } } +// java.io.InvalidClassException: remote.Person; local class incompatible: // + // stream classdesc serialVersionUID = 1687514539110537173, + // local class serialVersionUID = 510407729579040532 public static Object read(byte[] bs) { try { ByteArrayInputStream bais = new ByteArrayInputStream(bs);