Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 55c7bd4d authored by Deepanshu Gupta's avatar Deepanshu Gupta Committed by android-build-merger
Browse files

LayoutLib: Fix System.arraycopy()

automerge: 51fb7754

* commit '51fb7754':
  LayoutLib: Fix System.arraycopy()
parents 9e0ed1c2 51fb7754
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -131,8 +131,8 @@ valid StackMapTable. As a side benefit of this, we can continue to support Java
Mac has horrible font rendering support.

ReplaceMethodCallsAdapter replaces calls to certain methods. Currently, it only rewrites calls to
java.lang.System.arraycopy([CI[CII)V, which is not part of the Desktop VM to call the more general
method java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V.
specialized versions of java.lang.System.arraycopy(), which are not part of the Desktop VM to call
the more general method java.lang.System.arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V.

The ClassAdapters are chained together to achieve the desired output. (Look at section 2.2.7
Transformation chains in the asm user guide, link in the References.) The order of execution of
+2 −2
Original line number Diff line number Diff line
@@ -726,9 +726,9 @@ public class AsmAnalyzer {
                considerDesc(desc);


                // Check if method is java.lang.System.arrayCopy([CI[CII)V
                // Check if method is a specialized version of java.lang.System.arrayCopy()
                if (owner.equals("java/lang/System") && name.equals("arraycopy")
                        && desc.equals("([CI[CII)V")) {
                        && !desc.equals("(Ljava/lang/Object;ILjava/lang/Object;II)V")) {
                    mReplaceMethodCallClasses.add(mOwnerClass);
                }
            }
+19 −4
Original line number Diff line number Diff line
@@ -20,10 +20,23 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
 * Replaces calls to certain methods that do not exist in the Desktop VM.
 */
public class ReplaceMethodCallsAdapter extends ClassVisitor {

    /**
     * Descriptors for specialized versions {@link System#arraycopy} that are not present on the
     * Desktop VM.
     */
    private static Set<String> ARRAYCOPY_DESCRIPTORS = new HashSet<String>(Arrays.asList(
            "([CI[CII)V", "([BI[BII)V", "([SI[SII)V", "([II[III)V",
            "([JI[JII)V", "([FI[FII)V", "([DI[DII)V", "([ZI[ZII)V"));

    public ReplaceMethodCallsAdapter(ClassVisitor cv) {
        super(Opcodes.ASM4, cv);
    }
@@ -42,11 +55,13 @@ public class ReplaceMethodCallsAdapter extends ClassVisitor {

        @Override
        public void visitMethodInsn(int opcode, String owner, String name, String desc) {
            // Check if method is java.lang.System.arrayCopy([CI[CII)V
            if (owner.equals("java/lang/System") && name.equals("arraycopy")
                    && desc.equals("([CI[CII)V")) {
            // Check if method is a specialized version of java.lang.System.arrayCopy
            if (owner.equals("java/lang/System") && name.equals("arraycopy")) {

                if (ARRAYCOPY_DESCRIPTORS.contains(desc)) {
                    desc = "(Ljava/lang/Object;ILjava/lang/Object;II)V";
                }
            }
            super.visitMethodInsn(opcode, owner, name, desc);
        }
    }