bytedance / ByteX

ByteX is a bytecode plugin platform based on Android Gradle Transform API and ASM. 字节码插件开发平台
Apache License 2.0
3.13k stars 462 forks source link

method-call-opt-plugin 处理 Log 参数里带 if 时出现错误 #152

Open zyying opened 1 year ago

zyying commented 1 year ago

对于这样的 kotlin 代码:

class MethodCallKt {
    fun complex(forLogan: Boolean, tag: String, finalMsg: String) {
        Log.e(if (forLogan) "$tag[L]" else "${tag}[N]", finalMsg)
    }
}

Log.e 的参数里包含 if...else...,对应字节码是

public final complex(ZLjava/lang/String;Ljava/lang/String;)V
    // annotable parameter count: 3 (visible)
    // annotable parameter count: 3 (invisible)
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 1
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 2
   L0
    ALOAD 2
    LDC "tag"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
    ALOAD 3
    LDC "finalMsg"
    INVOKESTATIC kotlin/jvm/internal/Intrinsics.checkNotNullParameter (Ljava/lang/Object;Ljava/lang/String;)V
   L1
    LINENUMBER 7 L1
    ILOAD 1
    IFEQ L2
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    LDC "[L]"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
    GOTO L3
   L2
    NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    LDC "[N]"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
   L3
    ALOAD 3
    INVOKESTATIC android/util/Log.e (Ljava/lang/String;Ljava/lang/String;)I
    POP
   L4
    LINENUMBER 8 L4
    RETURN
   L5
    LOCALVARIABLE this Lcom/meituan/android/gradle/sample/method_call/MethodCallKt; L0 L5 0
    LOCALVARIABLE forLogan Z L0 L5 1
    LOCALVARIABLE tag Ljava/lang/String; L0 L5 2
    LOCALVARIABLE finalMsg Ljava/lang/String; L0 L5 3
    MAXSTACK = 2
    MAXLOCALS = 4

但是 method-call-opt-plugin 删除的代码是

NEW java/lang/StringBuilder
    DUP
    INVOKESPECIAL java/lang/StringBuilder.<init> ()V
    ALOAD 2
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    LDC "[N]"
    INVOKEVIRTUAL java/lang/StringBuilder.append (Ljava/lang/String;)Ljava/lang/StringBuilder;
    INVOKEVIRTUAL java/lang/StringBuilder.toString ()Ljava/lang/String;
   L3
    ALOAD 3
    INVOKESTATIC android/util/Log.e (Ljava/lang/String;Ljava/lang/String;)I
    POP

简单说就是只删除了 else 分支里的字节码指令,还有 Log.e 对应的字节码指令