ASM 3.3.1을 사용하고 있습니다. 클래스를 가로 채고 메소드 중 하나를 변경하려고합니다. org.objectweb.asm.util.ASMifierClassVisitor를 사용하여 ASM 코드를 가져와 새 메소드를 만듭니다. 모든 것은 훌륭하게 작동하지만 if() 문을 저주합니다. 결과 asm 코드를 if 문 (또는 루프)과 함께 사용하려고하면 런타임에 "스택 크기가 너무 큼"오류가 발생합니다. ClassWriter writer = new ClassWriter (ClassWriter.COMPUTE_FRAMES);를 사용하고 있습니다. 이것이 나에게주는 ASMIFY 코드입니다.Java 바이트 코드 ASM을 사용한 조작
if() 문을 ASMIFYING 할 때 오류가 발생하는 이유는 무엇입니까? 나는 어떤 도움을 크게 크게 감사 할 것입니다.
`mv = cw.visitMethod(ACC_PUBLIC, "doWrite", "(Lorg/apache/tomcat/util/buf/ByteChunk;)V", null, new String[] { "java/io/IOException" });
mv.visitCode();
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "req", "Lorg/apache/coyote/Request;");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/coyote/Request", "getParameters", "()Lorg/apache/tomcat/util/http/Parameters;");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/http/Parameters", "paramsAsString", "()Ljava/lang/String;");
mv.visitVarInsn(ASTORE, 2);
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
mv.visitLdcInsn("The Parameters are: ");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitVarInsn(ALOAD, 2);
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "req", "Lorg/apache/coyote/Request;");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/coyote/Request", "getParameters", "()Lorg/apache/tomcat/util/http/Parameters;");
mv.visitLdcInsn("json");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/http/Parameters", "getParameter", "(Ljava/lang/String;)Ljava/lang/String;");
mv.visitVarInsn(ASTORE, 3);
mv.visitVarInsn(ALOAD, 3);
Label l0 = new Label();
mv.visitJumpInsn(IFNULL, l0);
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitLdcInsn("###%#%#%$%#%#%#%#%#%#%#%##%#");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitLabel(l0);
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
mv.visitLdcInsn("Headers: ");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "headers", "Lorg/apache/tomcat/util/http/MimeHeaders;");
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/http/MimeHeaders", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitLdcInsn("\n");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
mv.visitTypeInsn(NEW, "java/lang/StringBuilder");
mv.visitInsn(DUP);
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuilder", "<init>", "()V");
mv.visitLdcInsn("Writeing: ");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/buf/ByteChunk", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitLdcInsn("\n");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "append", "(Ljava/lang/String;)Ljava/lang/StringBuilder;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;");
mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;)V");
mv.visitVarInsn(ALOAD, 0);
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "outputBuffer", "Lorg/apache/coyote/OutputBuffer;");
mv.visitVarInsn(ALOAD, 1);
mv.visitVarInsn(ALOAD, 0);
mv.visitMethodInsn(INVOKEINTERFACE, "org/apache/coyote/OutputBuffer", "doWrite", "(Lorg/apache/tomcat/util/buf/ByteChunk;Lorg/apache/coyote/Response;)I");
mv.visitInsn(POP);
mv.visitVarInsn(ALOAD, 0);
mv.visitInsn(DUP);
mv.visitFieldInsn(GETFIELD, "org/apache/coyote/Response", "bytesWritten", "J");
mv.visitVarInsn(ALOAD, 1);
mv.visitMethodInsn(INVOKEVIRTUAL, "org/apache/tomcat/util/buf/ByteChunk", "getLength", "()I");
mv.visitInsn(I2L);
mv.visitInsn(LADD);
mv.visitFieldInsn(PUTFIELD, "org/apache/coyote/Response", "bytesWritten", "J");
mv.visitInsn(RETURN);
mv.visitMaxs(5, 4);
mv.visitEnd();
`
코드 The ASMifying. (참고 : 나는 방법을 찍은 그게 내가 사용하고 전부로)
public void doWrite(ByteChunk chunk/*byte buffer[], int pos, int count*/)
throws IOException
{
String params=req.getParameters().paramsAsString();
System.out.println("The Parameters are: "+params);
String reqParam = req.getParameters().getParameter("json");
if(reqParam != null)
{
System.out.println("###%#%#%$%#%#%#%#%#%#%#%##%#");
}
System.out.println("Headers: " + headers.toString()+ "\n");
System.out.println("Writeing: " +chunk.toString()+"\n");
outputBuffer.doWrite(chunk, this);
bytesWritten+=chunk.getLength();
}
원래 메소드는 마지막 두 줄
outputBuffer.doWrite(chunk, this);
bytesWritten+=chunk.getLength();
이 잘 보이지 않는이 포함되어 있습니다. CheckClassAdapter.verify() 메소드를 사용하여 클래스의 일부분을 처리했습니다.
doWrite(Lorg/apache/tomcat/util/buf/ByteChunk;)V
00000 Response ByteChunk . . : : FRAME FULL [] []
00001 Response ByteChunk . . : : ALOAD 0
00002 Response ByteChunk . . : Response : GETFIELD org/apache/coyote/Response.req : Lorg/apache/coyote/Request;
00003 Response ByteChunk . . : Request : INVOKEVIRTUAL org/apache/coyote/Request.getParameters()Lorg/apache/tomcat/util/http/Parameters;
00004 Response ByteChunk . . : Parameters : INVOKEVIRTUAL org/apache/tomcat/util/http/Parameters.paramsAsString()Ljava/lang/String;
00005 Response ByteChunk . . : String : ASTORE 2
00006 Response ByteChunk String . : : GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
00007 Response ByteChunk String . : PrintStream : NEW java/lang/StringBuilder
00008 Response ByteChunk String . : PrintStream StringBuilder : DUP
00009 Response ByteChunk String . : PrintStream StringBuilder StringBuilder : INVOKESPECIAL java/lang/StringBuilder.<init>()V
00010 Response ByteChunk String . : PrintStream StringBuilder : LDC "The Parameters are: "
00011 Response ByteChunk String . : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00012 Response ByteChunk String . : PrintStream StringBuilder : ALOAD 2
00013 Response ByteChunk String . : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00014 Response ByteChunk String . : PrintStream StringBuilder : INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
00015 Response ByteChunk String . : PrintStream String : INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
00016 Response ByteChunk String . : : ALOAD 0
00017 Response ByteChunk String . : Response : GETFIELD org/apache/coyote/Response.req : Lorg/apache/coyote/Request;
00018 Response ByteChunk String . : Request : INVOKEVIRTUAL org/apache/coyote/Request.getParameters()Lorg/apache/tomcat/util/http/Parameters;
00019 Response ByteChunk String . : Parameters : LDC "json"
00020 Response ByteChunk String . : Parameters String : INVOKEVIRTUAL org/apache/tomcat/util/http/Parameters.getParameter (Ljava/lang/String;)Ljava/lang/String;
00021 Response ByteChunk String . : String : ASTORE 3
00022 Response ByteChunk String String : : ALOAD 3
00023 Response ByteChunk String String : String : IFNULL L0
00024 Response ByteChunk String String : : GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
00025 Response ByteChunk String String : PrintStream : LDC "###%#%#%$%#%#%#%#%#%#%#%##%#"
00026 Response ByteChunk String String : PrintStream String : INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
00027 Response ByteChunk String String : : L0
00028 Response ByteChunk String String : : FRAME FULL [org/apache/coyote/Response org/apache/tomcat/
00029 Response ByteChunk String String : : GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
00030 Response ByteChunk String String : PrintStream : NEW java/lang/StringBuilder
00031 Response ByteChunk String String : PrintStream StringBuilder : DUP
00032 Response ByteChunk String String : PrintStream StringBuilder StringBuilder : INVOKESPECIAL java/lang/StringBuilder.<init>()V
00033 Response ByteChunk String String : PrintStream StringBuilder : LDC "Headers: "
00034 Response ByteChunk String String : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00035 Response ByteChunk String String : PrintStream StringBuilder : ALOAD 0
00036 Response ByteChunk String String : PrintStream StringBuilder Response : GETFIELD org/apache/coyote/Response.headers : Lorg/apache/tomcat/util/http/MimeHeaders;
00037 Response ByteChunk String String : PrintStream StringBuilder MimeHeaders : INVOKEVIRTUAL org/apache/tomcat/util/http/MimeHeaders.toString()Ljava/lang/String;
00038 Response ByteChunk String String : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00039 Response ByteChunk String String : PrintStream StringBuilder : LDC "\n"
00040 Response ByteChunk String String : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00041 Response ByteChunk String String : PrintStream StringBuilder : INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
00042 Response ByteChunk String String : PrintStream String : INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
00043 Response ByteChunk String String : : GETSTATIC java/lang/System.out : Ljava/io/PrintStream;
00044 Response ByteChunk String String : PrintStream : NEW java/lang/StringBuilder
00045 Response ByteChunk String String : PrintStream StringBuilder : DUP
00046 Response ByteChunk String String : PrintStream StringBuilder StringBuilder : INVOKESPECIAL java/lang/StringBuilder.<init>()V
00047 Response ByteChunk String String : PrintStream StringBuilder : LDC "Writeing: "
00048 Response ByteChunk String String : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00049 Response ByteChunk String String : PrintStream StringBuilder : ALOAD 1
00050 Response ByteChunk String String : PrintStream StringBuilder ByteChunk : INVOKEVIRTUAL org/apache/tomcat/util/buf/ByteChunk.toString()Ljava/lang/String;
00051 Response ByteChunk String String : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00052 Response ByteChunk String String : PrintStream StringBuilder : LDC "\n"
00053 Response ByteChunk String String : PrintStream StringBuilder String : INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
00054 Response ByteChunk String String : PrintStream StringBuilder : INVOKEVIRTUAL java/lang/StringBuilder.toString()Ljava/lang/String;
00055 Response ByteChunk String String : PrintStream String : INVOKEVIRTUAL java/io/PrintStream.println (Ljava/lang/String;)V
00056 Response ByteChunk String String : : ALOAD 0
00057 Response ByteChunk String String : Response : GETFIELD org/apache/coyote/Response.outputBuffer : Lorg/apache/coyote/OutputBuffer;
00058 Response ByteChunk String String : OutputBuffer : ALOAD 1
00059 Response ByteChunk String String : OutputBuffer ByteChunk : ALOAD 0
00060 Response ByteChunk String String : OutputBuffer ByteChunk Response : INVOKEINTERFACE org/apache/coyote/OutputBuffer.doWrite (Lorg/apache/tomcat/util/buf/ByteChunk;Lorg/apache/coyote/Response;)I
00061 Response ByteChunk String String : I : POP
00062 Response ByteChunk String String : : ALOAD 0
00063 Response ByteChunk String String : Response : DUP
00064 Response ByteChunk String String : Response Response : GETFIELD org/apache/coyote/Response.bytesWritten : J
00065 Response ByteChunk String String : Response J : ALOAD 1
00066 Response ByteChunk String String : Response J ByteChunk : INVOKEVIRTUAL org/apache/tomcat/util/buf/ByteChunk.getLength()I
00067 Response ByteChunk String String : Response J I : I2L
00068 Response ByteChunk String String : Response J J : LADD
00069 Response ByteChunk String String : Response J : PUTFIELD org/apache/coyote/Response.bytesWritten : J
00070 Response ByteChunk String String : : RETURN
00071 ? : NOP
00072 ? : NOP
00073 ? : NOP
00074 ? : NOP
00075 ? : NOP
00076 ? : NOP
00077 ? : NOP
00078 ? : NOP
00079 ? : NOP
00080 ? : NOP
00081 ? : NOP
00082 ? : NOP
00083 ? : NOP
00084 ? : NOP
00085 ? : NOP
00086 ? : NOP
00087 ? : NOP
00088 ? : NOP
00089 ? : NOP
00090 ? : NOP
00091 ? : NOP
00092 ? : NOP
00093 ? : NOP
00094 ? : NOP
00095 ? : NOP
00096 ? : NOP
00097 ? : ATHROW
작성중인 비 ASM 코드를 게시 할 수 있습니까? 그런 식으로 당신의 의도를 더 쉽게 읽을 수 있다면, 당신이 만드는 ASM이 왜 스택과 논쟁을하고 있는지 알아낼 수 있습니다. –
좋아, 나는 ASMifying 코드를 업데이트했다. – Chris
(개인적으로 저는이 모든 것을 손으로 건너 뛰고 AspectJ를 사용하지 않을 것입니다.) –