From 9fafdb2df0b2474c9645053882084e958a12a128 Mon Sep 17 00:00:00 2001 From: Rafael Winterhalter Date: Sat, 9 Apr 2016 13:49:51 +0200 Subject: [PATCH] Fixed field access implementation. --- .../main/java/net/bytebuddy/asm/Advice.java | 103 ++++++++---------- 1 file changed, 47 insertions(+), 56 deletions(-) diff --git a/byte-buddy-dep/src/main/java/net/bytebuddy/asm/Advice.java b/byte-buddy-dep/src/main/java/net/bytebuddy/asm/Advice.java index 709c80b3f35..34446652314 100644 --- a/byte-buddy-dep/src/main/java/net/bytebuddy/asm/Advice.java +++ b/byte-buddy-dep/src/main/java/net/bytebuddy/asm/Advice.java @@ -1968,7 +1968,7 @@ public String toString() { /** * An offset mapping for a field. */ - class ForField implements Target { + class ForReadOnlyField implements Target { /** * The field being read. @@ -1980,7 +1980,7 @@ class ForField implements Target { * * @param fieldDescription The field being read. */ - protected ForField(FieldDescription fieldDescription) { + protected ForReadOnlyField(FieldDescription fieldDescription) { this.fieldDescription = fieldDescription; } @@ -1990,40 +1990,9 @@ public int resolveAccess(MethodVisitor methodVisitor, int opcode) { case Opcodes.ISTORE: case Opcodes.ASTORE: case Opcodes.FSTORE: - if (fieldDescription.isStatic()) { - methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, - fieldDescription.getDeclaringType().asErasure().getInternalName(), - fieldDescription.getInternalName(), - fieldDescription.getDescriptor()); - return NO_PADDING; - } else { - methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); - methodVisitor.visitInsn(Opcodes.DUP_X1); - methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, - fieldDescription.getDeclaringType().asErasure().getInternalName(), - fieldDescription.getInternalName(), - fieldDescription.getDescriptor()); - methodVisitor.visitInsn(Opcodes.POP); - return 2; - } case Opcodes.LSTORE: case Opcodes.DSTORE: - if (fieldDescription.isStatic()) { - methodVisitor.visitFieldInsn(Opcodes.PUTSTATIC, - fieldDescription.getDeclaringType().asErasure().getInternalName(), - fieldDescription.getInternalName(), - fieldDescription.getDescriptor()); - return NO_PADDING; - } else { - methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); - methodVisitor.visitInsn(Opcodes.DUP_X2); - methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, - fieldDescription.getDeclaringType().asErasure().getInternalName(), - fieldDescription.getInternalName(), - fieldDescription.getDescriptor()); - methodVisitor.visitInsn(Opcodes.POP2); - return 3; - } + throw new IllegalStateException("Cannot write to field: " + fieldDescription); case Opcodes.ILOAD: case Opcodes.FLOAD: case Opcodes.ALOAD: @@ -2040,22 +2009,16 @@ public int resolveAccess(MethodVisitor methodVisitor, int opcode) { fieldDescription.getDeclaringType().asErasure().getInternalName(), fieldDescription.getInternalName(), fieldDescription.getDescriptor()); - return NO_PADDING; + break; default: throw new IllegalArgumentException("Did not expect opcode: " + opcode); } + return NO_PADDING; } @Override public int resolveIncrement(MethodVisitor methodVisitor, int increment) { - methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); - methodVisitor.visitInsn(Opcodes.DUP_X1); - methodVisitor.visitFieldInsn(Opcodes.PUTFIELD, - fieldDescription.getDeclaringType().asErasure().getInternalName(), - fieldDescription.getInternalName(), - fieldDescription.getDescriptor()); - methodVisitor.visitInsn(Opcodes.POP); - return 2; + throw new IllegalStateException("Cannot write to field: " + fieldDescription); } @Override @@ -2082,7 +2045,7 @@ public String toString() { /** * An offset mapping for a field. */ - class ForReadOnlyField implements Target { + class ForField implements Target { /** * The field being read. @@ -2094,7 +2057,7 @@ class ForReadOnlyField implements Target { * * @param fieldDescription The field being read. */ - protected ForReadOnlyField(FieldDescription fieldDescription) { + protected ForField(FieldDescription fieldDescription) { this.fieldDescription = fieldDescription; } @@ -2104,35 +2067,63 @@ public int resolveAccess(MethodVisitor methodVisitor, int opcode) { case Opcodes.ISTORE: case Opcodes.ASTORE: case Opcodes.FSTORE: + if (!fieldDescription.isStatic()) { + methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); + methodVisitor.visitInsn(Opcodes.DUP_X1); + methodVisitor.visitInsn(Opcodes.POP); + accessField(methodVisitor, Opcodes.PUTFIELD); + return 2; + } case Opcodes.LSTORE: case Opcodes.DSTORE: - throw new IllegalStateException("Cannot write to field: " + fieldDescription); + if (!fieldDescription.isStatic()) { + methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); + methodVisitor.visitInsn(Opcodes.DUP_X2); + methodVisitor.visitInsn(Opcodes.POP); + accessField(methodVisitor, Opcodes.PUTFIELD); + return 2; + } + accessField(methodVisitor, Opcodes.PUTSTATIC); + return NO_PADDING; case Opcodes.ILOAD: case Opcodes.FLOAD: case Opcodes.ALOAD: case Opcodes.LLOAD: case Opcodes.DLOAD: - int accessOpcode; if (fieldDescription.isStatic()) { - accessOpcode = Opcodes.GETSTATIC; + accessField(methodVisitor, Opcodes.GETSTATIC); } else { methodVisitor.visitVarInsn(Opcodes.ALOAD, 0); - accessOpcode = Opcodes.GETFIELD; + accessField(methodVisitor, Opcodes.GETFIELD); } - methodVisitor.visitFieldInsn(accessOpcode, - fieldDescription.getDeclaringType().asErasure().getInternalName(), - fieldDescription.getInternalName(), - fieldDescription.getDescriptor()); - break; + return NO_PADDING; default: throw new IllegalArgumentException("Did not expect opcode: " + opcode); } - return NO_PADDING; } @Override public int resolveIncrement(MethodVisitor methodVisitor, int increment) { - throw new IllegalStateException("Cannot write to field: " + fieldDescription); + if (fieldDescription.isStatic()) { + accessField(methodVisitor, Opcodes.GETFIELD); + methodVisitor.visitInsn(Opcodes.IINC); + accessField(methodVisitor, Opcodes.PUTFIELD); + return NO_PADDING; + } else { + methodVisitor.visitIntInsn(Opcodes.ALOAD, 0); + methodVisitor.visitInsn(Opcodes.DUP); + accessField(methodVisitor, Opcodes.GETSTATIC); + methodVisitor.visitInsn(Opcodes.IINC); + accessField(methodVisitor, Opcodes.PUTSTATIC); + return 2; + } + } + + private void accessField(MethodVisitor methodVisitor, int opcode) { + methodVisitor.visitFieldInsn(opcode, + fieldDescription.getDeclaringType().asErasure().getInternalName(), + fieldDescription.getInternalName(), + fieldDescription.getDescriptor()); } @Override