簡體   English   中英

ASM 創建帶有參數名稱的方法 w/ ClassWriter

[英]ASM create method with parameter name w/ ClassWriter

Kotlin 使用 org.objectweb.asm 庫的代碼

import org.objectweb.asm.ClassWriter
import org.objectweb.asm.Opcodes.*

fun main(args: Array<String>) {
    val classWriter = ClassWriter(ClassWriter.COMPUTE_MAXS)

    classWriter.visit(
            V1_8,
            ACC_PUBLIC,
            "com/github/patrick/learnasm/build/HelloWorld",
            null,
            "java/lang/Object",
            null
    )

    val methodVisitor = classWriter.visitMethod(
            ACC_PUBLIC + ACC_STATIC,
            "main",
            "([Ljava/lang/String;)V",
            null,
            null
    )

    methodVisitor.visitFieldInsn(
            GETSTATIC,
            "java/lang/System",
            "out",
            "Ljava/io/PrintStream;"
    )

    methodVisitor.visitLdcInsn(
            "Hello World!"
    )

    methodVisitor.visitMethodInsn(
            INVOKEVIRTUAL,
            "java/io/PrintStream",
            "println",
            "(Ljava/lang/String;)V",
            false
    )

    methodVisitor.visitInsn(
            RETURN
    )

    methodVisitor.visitMaxs(
            0,
            0
    )

    methodVisitor.visitEnd()

    val bytes = classWriter.toByteArray()
    val clazz = defineClass(
            "com.github.patrick.learnasm.build.HelloWorld",
            bytes,
            0,
            bytes.count()
    )

    clazz.getDeclaredMethod("main", Array<String>::class.java).invoke(null, null)
}

我正在嘗試學習 asm,我很好奇是否可以創建具有命名參數的方法。

例如在這種情況下,創建的 class 沒有參數名稱(在反編譯器中默認為 var0),我希望我可以保存參數名稱,如“args”。 可能嗎?

通過查看已編譯的 class 找到答案(通過包含調試信息)

簡單的方法就是模擬編譯后的 class

我所要做的就是在上面放一些 label,然后訪問帶有名稱的局部變量。

            methodVisitor = classWriter.visitMethod(
                    Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC,
                    "main",
                    "([Ljava/lang/String;)V",
                    null,
                    null
            )

            methodVisitor.visitParameterAnnotation(
                    0,
                    "Lorg.jetbrains.annotations.NotNull;",
                    false
            )

            val start = Label()
            methodVisitor.visitLabel(start)

            methodVisitor.visitFieldInsn(
                    Opcodes.GETSTATIC,
                    "java/lang/System",
                    "out",
                    "Ljava/io/PrintStream;"
            )

            methodVisitor.visitLdcInsn("Hello World!")

            methodVisitor.visitMethodInsn(
                    Opcodes.INVOKEVIRTUAL,
                    "java/io/PrintStream",
                    "println",
                    "(Ljava/lang/String;)V",
                    false
            )

            methodVisitor.visitInsn(Opcodes.RETURN)

            val end = Label()
            methodVisitor.visitLabel(end)

            methodVisitor.visitLocalVariable(
                    "args",
                    "[Ljava/lang/String;",
                    null,
                    start,
                    end,
                    0
            )

            methodVisitor.visitMaxs(0, 0)
            methodVisitor.visitEnd()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM