Skip to content

fix: fix inlining synthetic accessors#2243

Merged
skylot merged 2 commits intoskylot:masterfrom
pubiqq:fix-inlining-synthetic-accessors
Aug 8, 2024
Merged

fix: fix inlining synthetic accessors#2243
skylot merged 2 commits intoskylot:masterfrom
pubiqq:fix-inlining-synthetic-accessors

Conversation

@pubiqq
Copy link
Contributor

@pubiqq pubiqq commented Aug 7, 2024

No description provided.

@pubiqq pubiqq force-pushed the fix-inlining-synthetic-accessors branch from 356b4e8 to 95fcf45 Compare August 7, 2024 19:32
@skylot
Copy link
Owner

skylot commented Aug 7, 2024

@pubiqq can you share test case for this issue (smali or apk sample with method names)?
I will prepare a regression test.

@pubiqq
Copy link
Contributor Author

pubiqq commented Aug 8, 2024

Case 1: no args

  • Without fix: not inlines
  • With fix: inlines
  • Smali

    .method static synthetic access$000()Lsun/misc/Unsafe;
        .registers 1
    
        .line 26
        invoke-static {}, Lcom/google/common/cache/Striped64;->getUnsafe()Lsun/misc/Unsafe;
    
        move-result-object v0
    
        return-object v0
    .end method
    

Case 2: 1 arg

  • Without fix: inlines
  • With fix: inlines
  • Smali

    .method static synthetic access$000(I)Z
        .registers 2
        .param p0, "x0"    # I
    
        .line 23
        invoke-static {p0}, Lcom/google/android/exoplayer2/audio/MpegAudioUtil;->isMagicPresent(I)Z
    
        move-result v0
    
        return v0
    .end method
    

Case 3: 2 args

  • Without fix: inlines
  • With fix: inlines
  • Smali

    .method static synthetic access$300(II)I
        .registers 3
        .param p0, "x0"    # I
        .param p1, "x1"    # I
    
        .line 23
        invoke-static {p0, p1}, Lcom/google/android/exoplayer2/audio/MpegAudioUtil;->getFrameSizeInSamples(II)I
    
        move-result v0
    
        return v0
    .end method
    

Case 4 (the reason for creating the PR)

  • Without fix: JadxRuntimeException: Failed to process method for inline <...>
  • With fix: inlines
  • Smali (full class)

    ###### Class com.example.TestJavaClass (com.example.TestJavaClass)
    .class Lcom/example/TestJavaClass;
    .super Ljava/lang/Object;
    .source "TestJavaClass.java"
    
    
    # direct methods
    .method constructor <init>()V
        .registers 1
    
        .line 5
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
        return-void
    .end method
    
    .method static synthetic lambda$test$0(JJ)Ljava/lang/Long;
        .registers 8
        .param p0, "x1"    # J
        .param p2, "x2"    # J
    
        .line 9
        invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
    
        move-result-wide v0
    
        .line 10
        .local v0, "y1":J
        add-long v2, p0, v0
    
        add-long/2addr v2, p2
    
        invoke-static {v2, v3}, Ljava/lang/Long;->valueOf(J)Ljava/lang/Long;
    
        move-result-object v2
    
        return-object v2
    .end method
    
    .method static test(JJ)Ljava/util/function/Supplier;
        .registers 5
        .param p0, "x1"    # J
        .param p2, "x2"    # J
        .annotation system Ldalvik/annotation/Signature;
            value = {
                "(JJ)",
                "Ljava/util/function/Supplier<",
                "Ljava/lang/Long;",
                ">;"
            }
        .end annotation
    
        .line 8
        new-instance v0, Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;
    
        invoke-direct {v0, p0, p1, p2, p3}, Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;-><init>(JJ)V
    
        return-object v0
    .end method
    
    ###### Class com.example.TestJavaClass$$ExternalSyntheticLambda0 (com.example.TestJavaClass$$ExternalSyntheticLambda0)
    .class public final synthetic Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;
    .super Ljava/lang/Object;
    .source "D8$$SyntheticClass"
    
    # interfaces
    .implements Ljava/util/function/Supplier;
    
    
    # instance fields
    .field public final synthetic f$0:J
    
    .field public final synthetic f$1:J
    
    
    # direct methods
    .method public synthetic constructor <init>(JJ)V
        .registers 5
    
        invoke-direct {p0}, Ljava/lang/Object;-><init>()V
    
        iput-wide p1, p0, Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;->f$0:J
    
        iput-wide p3, p0, Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;->f$1:J
    
        return-void
    .end method
    
    
    # virtual methods
    .method public final get()Ljava/lang/Object;
        .registers 5
    
        iget-wide v0, p0, Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;->f$0:J
    
        iget-wide v2, p0, Lcom/example/TestJavaClass$$ExternalSyntheticLambda0;->f$1:J
    
        invoke-static {v0, v1, v2, v3}, Lcom/example/TestJavaClass;->lambda$test$0(JJ)Ljava/lang/Long;
    
        move-result-object v0
    
        return-object v0
    .end method
    
    

@pubiqq
Copy link
Contributor Author

pubiqq commented Aug 8, 2024

Actually, methods can be inlined even more aggressively, but I'd like to wait for the lambdas to be fixed first.

@skylot
Copy link
Owner

skylot commented Aug 8, 2024

@pubiqq thanks 👍
I commit several changes:

  • add test (only for 4th case)
  • undo adding new field into InsnNode: we don't really needed to enforce args list immutability, also I don't want to change method return type, because it is part of public API and can be used in external plugins/scripts. So I just add a new method to get args list 🤣
  • wrap inline checks code into try/catch to not fail method decompilation, just skip method inline.

@skylot skylot merged commit 60fb458 into skylot:master Aug 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants