Upgrade google-smali to 3.0.3 am: d166abb294 am: 184671072b am: b2fd0c6881

Original change: https://android-review.googlesource.com/c/platform/external/google-smali/+/2673480

Change-Id: I21d06c3da9f4f226e27aa023afcf5368cc9cd18c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/METADATA b/METADATA
index 79c275d..293b194 100644
--- a/METADATA
+++ b/METADATA
@@ -1,6 +1,6 @@
 # This project was upgraded with external_updater.
 # Usage: tools/external_updater/updater.sh update google-smali
-# For more info, check https://cs.android.com/android/platform/superproject/+/master:tools/external_updater/README.md
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
 
 name: "google-smali"
 description: "smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android\'s Java VM implementation."
@@ -9,11 +9,11 @@
     type: GIT
     value: "https://github.com/google/smali"
   }
-  version: "3.0.2"
+  version: "3.0.3"
   license_type: NOTICE
   last_upgrade_date {
     year: 2023
-    month: 4
-    day: 11
+    month: 7
+    day: 24
   }
 }
diff --git a/README.md b/README.md
index 265875e..8a0ea4d 100644
--- a/README.md
+++ b/README.md
@@ -2,11 +2,13 @@
 
 smali/baksmali is an assembler/disassembler for the dex format used by dalvik, Android's Java VM implementation. The syntax is loosely based on Jasmin's/dedexer's syntax, and supports the full functionality of the dex format (annotations, debug info, line info, etc.)
 
-**NOTE**: This is a fork of https://github.com/JesusFreke/smali for patches needed by Google as the original repository is currently not maintained. After forking the namespace was changed from `org.jf` to `com.anroid.tools.smali`. The artifacts are released on [Google Maven](https://maven.google.com) under the following coordinates:
-* [com.anroid.tools.smali:smali:<version>](https://maven.google.com/web/index.html?q=smali#com.android.tools.smali:smali)
-* [com.anroid.tools.smali:smali-dexlib2:<version>](https://maven.google.com/web/index.html?q=smali-dexlib2#com.android.tools.smali:smali-dexlib2)
-* [com.anroid.tools.smali:smali-baksmali:<version>](https://maven.google.com/web/index.html?q=smali-baksmali#com.android.tools.smali:smali)
-* [com.anroid.tools.smali:smali-util:<version>](https://maven.google.com/web/index.html?q=smali-util#com.android.tools.smali:smali-util)
+**NOTE**: This is a fork of https://github.com/JesusFreke/smali for patches needed by Google as the original repository is currently not maintained. After forking the namespace was changed from `org.jf` to `com.android.tools.smali`. The artifacts are released on [Google Maven](https://maven.google.com) under the following coordinates:
+
+* [`com.android.tools.smali:smali:<version>`](https://maven.google.com/web/index.html?q=smali#com.android.tools.smali:smali)
+* [`com.android.tools.smali:smali-dexlib2:<version>`](https://maven.google.com/web/index.html?q=smali-dexlib2#com.android.tools.smali:smali-dexlib2)
+* [`com.android.tools.smali:smali-baksmali:<version>`](https://maven.google.com/web/index.html?q=smali-baksmali#com.android.tools.smali:smali)
+* [`com.android.tools.smali:smali-util:<version>`](https://maven.google.com/web/index.html?q=smali-util#com.android.tools.smali:smali-util)
+
 After the fork the first version released was 3.0.0, which was version 2.5.2 from the original repo with a few patches and the namespace change.
 
 #### Support
@@ -49,3 +51,21 @@
 ```
 ./gradlew release publishToMavenLocal
 ```
+
+### Prepare and build a release version
+To prepare a release update `build.gradle` with the next release version and commit that.
+Then create a tag for that commit with the version.
+```
+git tag <version> <commit>
+git push origin <version>
+```
+Release versions can then be built by the Google R8 team using:
+```
+tools/trigger.py --smali=<version> --release
+```
+in the R8 repository.
+
+The status of the build on the bot is at https://ci.chromium.org/p/r8/builders/ci/smali.
+
+### Releasing versions on Google Maven
+TBD.
diff --git a/build.gradle b/build.gradle
index f0e766a..c758163 100644
--- a/build.gradle
+++ b/build.gradle
@@ -30,7 +30,7 @@
 
 apply plugin: 'idea'
 
-version = '3.0.2'
+version = '3.0.3'
 def jcommanderVersion = ''
 
 if (!('release' in gradle.startParameter.taskNames)) {
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedDexFile.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedDexFile.java
index 4f1b88f..93d7581 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedDexFile.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/dexbacked/DexBackedDexFile.java
@@ -272,6 +272,12 @@
                 return getMethodSection();
             case ReferenceType.FIELD:
                 return getFieldSection();
+            case ReferenceType.METHOD_PROTO:
+                return getMethodSection();
+            case ReferenceType.METHOD_HANDLE:
+                return getMethodHandleSection();
+            case ReferenceType.CALL_SITE:
+                return getCallSiteSection();
             default:
                 throw new IllegalArgumentException(String.format("Invalid reference type: %d", referenceType));
         }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java
new file mode 100644
index 0000000..d19cebf
--- /dev/null
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/CallSiteReferenceRewriter.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright 2023, Google LLC
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ * Neither the name of Google LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.tools.smali.dexlib2.rewriter;
+
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
+import com.android.tools.smali.dexlib2.base.reference.BaseCallSiteReference;
+import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
+import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
+
+import javax.annotation.Nonnull;
+import java.util.List;
+
+public class CallSiteReferenceRewriter implements Rewriter<CallSiteReference> {
+    @Nonnull protected final Rewriters rewriters;
+
+    public CallSiteReferenceRewriter(@Nonnull Rewriters rewriters) {
+        this.rewriters = rewriters;
+    }
+
+    @Nonnull @Override public CallSiteReference rewrite(@Nonnull CallSiteReference callSiteReference) {
+        return new RewrittenCallSiteReference(callSiteReference);
+    }
+
+    protected class RewrittenCallSiteReference extends BaseCallSiteReference {
+        @Nonnull protected CallSiteReference callSiteReference;
+
+        public RewrittenCallSiteReference(@Nonnull CallSiteReference callSiteReference) {
+            this.callSiteReference = callSiteReference;
+        }
+
+        @Override @Nonnull public String getName() {
+            return callSiteReference.getName();
+        }
+
+        @Override @Nonnull public MethodHandleReference getMethodHandle() {
+                return RewriterUtils.rewriteMethodHandleReference(
+                        rewriters, callSiteReference.getMethodHandle());
+        }
+
+        @Override @Nonnull public String getMethodName() {
+            return callSiteReference.getMethodName();
+        }
+
+        @Override @Nonnull public MethodProtoReference getMethodProto() {
+            return RewriterUtils.rewriteMethodProtoReference(
+                        rewriters.getTypeRewriter(),
+                        callSiteReference.getMethodProto());
+        }
+
+        @Override @Nonnull public List<? extends EncodedValue> getExtraArguments() {
+            return Lists.transform(callSiteReference.getExtraArguments(),
+                    new Function<EncodedValue, EncodedValue>() {
+                        @Nonnull @Override public EncodedValue apply(EncodedValue encodedValue) {
+                            return RewriterUtils.rewriteValue(rewriters, encodedValue);
+                        }
+                    });
+        }
+    }
+}
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/DexRewriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/DexRewriter.java
index ed286b3..dfdba7e 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/DexRewriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/DexRewriter.java
@@ -42,6 +42,7 @@
 import com.android.tools.smali.dexlib2.iface.TryBlock;
 import com.android.tools.smali.dexlib2.iface.debug.DebugItem;
 import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
+import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
 import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
 import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
@@ -87,6 +88,7 @@
     private final Rewriter<String> typeRewriter;
     private final Rewriter<FieldReference> fieldReferenceRewriter;
     private final Rewriter<MethodReference> methodReferenceRewriter;
+    private final Rewriter<CallSiteReference> callSiteReferenceRewriter;
     private final Rewriter<Annotation> annotationRewriter;
     private final Rewriter<AnnotationElement> annotationElementRewriter;
     private final Rewriter<EncodedValue> encodedValueRewriter;
@@ -105,6 +107,7 @@
         this.typeRewriter = module.getTypeRewriter(this);
         this.fieldReferenceRewriter = module.getFieldReferenceRewriter(this);
         this.methodReferenceRewriter = module.getMethodReferenceRewriter(this);
+        this.callSiteReferenceRewriter = module.getCallSiteReferenceRewriter(this);
         this.annotationRewriter = module.getAnnotationRewriter(this);
         this.annotationElementRewriter = module.getAnnotationElementRewriter(this);
         this.encodedValueRewriter = module.getEncodedValueRewriter(this);
@@ -123,6 +126,7 @@
     @Nonnull @Override public Rewriter<String> getTypeRewriter() { return typeRewriter; }
     @Nonnull @Override public Rewriter<FieldReference> getFieldReferenceRewriter() { return fieldReferenceRewriter; }
     @Nonnull @Override public Rewriter<MethodReference> getMethodReferenceRewriter() { return methodReferenceRewriter; }
+    @Nonnull @Override public Rewriter<CallSiteReference> getCallSiteReferenceRewriter() { return callSiteReferenceRewriter; }
     @Nonnull @Override public Rewriter<Annotation> getAnnotationRewriter() { return annotationRewriter; }
     @Nonnull @Override public Rewriter<AnnotationElement> getAnnotationElementRewriter() { return annotationElementRewriter; }
     @Nonnull @Override public Rewriter<EncodedValue> getEncodedValueRewriter() { return encodedValueRewriter; }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/InstructionRewriter.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/InstructionRewriter.java
index b346839..af4ba88 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/InstructionRewriter.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/InstructionRewriter.java
@@ -32,6 +32,7 @@
 
 import com.android.tools.smali.dexlib2.Opcode;
 import com.android.tools.smali.dexlib2.ReferenceType;
+import com.android.tools.smali.dexlib2.iface.instruction.DualReferenceInstruction;
 import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
 import com.android.tools.smali.dexlib2.iface.instruction.ReferenceInstruction;
 import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction20bc;
@@ -41,10 +42,15 @@
 import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction35c;
 import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction3rc;
 import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction45cc;
+import com.android.tools.smali.dexlib2.iface.instruction.formats.Instruction4rcc;
+import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
 import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
 import com.android.tools.smali.dexlib2.iface.reference.Reference;
 import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
+import com.android.tools.smali.util.ExceptionWithContext;
 
 import javax.annotation.Nonnull;
 
@@ -72,6 +78,8 @@
                     return new RewrittenInstruction3rc((Instruction3rc)instruction);
                 case Format45cc:
                     return new RewrittenInstruction45cc((Instruction45cc) instruction);
+                case Format4rcc:
+                    return new RewrittenInstruction4rcc((Instruction4rcc) instruction);
                 default:
                     throw new IllegalArgumentException();
             }
@@ -79,6 +87,33 @@
         return instruction;
     }
 
+    @Nonnull private Reference rewriteReference(int type,
+                                                @Nonnull Reference reference) {
+        switch (type) {
+            case ReferenceType.TYPE:
+                return RewriterUtils.rewriteTypeReference(rewriters.getTypeRewriter(),
+                        (TypeReference)reference);
+            case ReferenceType.FIELD:
+                return rewriters.getFieldReferenceRewriter().rewrite((FieldReference)reference);
+            case ReferenceType.METHOD:
+                return rewriters.getMethodReferenceRewriter().rewrite((MethodReference)reference);
+            case ReferenceType.STRING:
+                return reference;
+            case ReferenceType.METHOD_PROTO:
+                return RewriterUtils.rewriteMethodProtoReference(
+                        rewriters.getTypeRewriter(),
+                        (MethodProtoReference)reference);
+            case ReferenceType.METHOD_HANDLE:
+                return RewriterUtils.rewriteMethodHandleReference(
+                        rewriters, (MethodHandleReference)reference);
+            case ReferenceType.CALL_SITE:
+                return rewriters.getCallSiteReferenceRewriter().rewrite((CallSiteReference)reference);
+            default:
+                throw new ExceptionWithContext("Invalid reference type: %d",
+                                type);
+        }
+    }
+
     protected class BaseRewrittenReferenceInstruction<T extends ReferenceInstruction>
             implements ReferenceInstruction {
         @Nonnull protected T instruction;
@@ -88,19 +123,8 @@
         }
 
         @Override @Nonnull public Reference getReference() {
-            switch (instruction.getReferenceType()) {
-                case ReferenceType.TYPE:
-                    return RewriterUtils.rewriteTypeReference(rewriters.getTypeRewriter(),
-                            (TypeReference)instruction.getReference());
-                case ReferenceType.FIELD:
-                    return rewriters.getFieldReferenceRewriter().rewrite((FieldReference)instruction.getReference());
-                case ReferenceType.METHOD:
-                    return rewriters.getMethodReferenceRewriter().rewrite((MethodReference)instruction.getReference());
-                case ReferenceType.STRING:
-                    return instruction.getReference();
-                default:
-                    throw new IllegalArgumentException();
-            }
+            return rewriteReference(
+                instruction.getReferenceType(), instruction.getReference());
         }
 
         @Override public int getReferenceType() {
@@ -210,33 +234,28 @@
         }
     }
 
-    protected class RewrittenInstruction45cc extends BaseRewrittenReferenceInstruction<Instruction45cc>
-            implements Instruction45cc {
-        public RewrittenInstruction45cc(@Nonnull Instruction45cc instruction) {
+    protected class BaseRewrittenDualReferenceInstruction<T extends DualReferenceInstruction>
+            extends BaseRewrittenReferenceInstruction<T>
+            implements DualReferenceInstruction {
+        public BaseRewrittenDualReferenceInstruction(@Nonnull T instruction) {
             super(instruction);
         }
 
         @Nonnull public Reference getReference2() {
-            switch (instruction.getReferenceType2()) {
-                case ReferenceType.TYPE:
-                    return RewriterUtils.rewriteTypeReference(rewriters.getTypeRewriter(),
-                            (TypeReference)instruction.getReference2());
-                case ReferenceType.FIELD:
-                    return rewriters.getFieldReferenceRewriter().rewrite((FieldReference)instruction.getReference2());
-                case ReferenceType.METHOD:
-                    return rewriters.getMethodReferenceRewriter().rewrite((MethodReference)instruction.getReference2());
-                case ReferenceType.STRING:
-                    return instruction.getReference2();
-                case ReferenceType.METHOD_PROTO:
-                    return instruction.getReference2();
-                default:
-                    throw new IllegalArgumentException();
-            }
+            return rewriteReference(
+                instruction.getReferenceType2(), instruction.getReference2());
         }
 
         public int getReferenceType2() {
             return instruction.getReferenceType2();
         }
+    }
+
+    protected class RewrittenInstruction45cc extends BaseRewrittenDualReferenceInstruction<Instruction45cc>
+            implements Instruction45cc {
+        public RewrittenInstruction45cc(@Nonnull Instruction45cc instruction) {
+            super(instruction);
+        }
 
         public int getRegisterC() {
             return instruction.getRegisterC();
@@ -262,4 +281,19 @@
             return instruction.getRegisterF();
         }
     }
+
+    protected class RewrittenInstruction4rcc extends BaseRewrittenDualReferenceInstruction<Instruction4rcc>
+            implements Instruction4rcc {
+        public RewrittenInstruction4rcc(@Nonnull Instruction4rcc instruction) {
+            super(instruction);
+        }
+
+        public int getStartRegister() {
+            return instruction.getStartRegister();
+        }
+
+        public int getRegisterCount() {
+            return instruction.getRegisterCount();
+        }
+    }
 }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterModule.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterModule.java
index 9762c89..0762b5f 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterModule.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterModule.java
@@ -42,6 +42,7 @@
 import com.android.tools.smali.dexlib2.iface.TryBlock;
 import com.android.tools.smali.dexlib2.iface.debug.DebugItem;
 import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
+import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
 import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
 import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
@@ -101,6 +102,10 @@
         return new MethodReferenceRewriter(rewriters);
     }
 
+    @Nonnull public Rewriter<CallSiteReference> getCallSiteReferenceRewriter(@Nonnull Rewriters rewriters) {
+        return new CallSiteReferenceRewriter(rewriters);
+    }
+
     @Nonnull public Rewriter<Annotation> getAnnotationRewriter(@Nonnull Rewriters rewriters) {
         return new AnnotationRewriter(rewriters);
     }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java
index a829754..652eb46 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/RewriterUtils.java
@@ -30,8 +30,31 @@
 
 package com.android.tools.smali.dexlib2.rewriter;
 
+import com.android.tools.smali.util.ExceptionWithContext;
+import com.android.tools.smali.dexlib2.MethodHandleType;
+import com.android.tools.smali.dexlib2.ValueType;
+import com.android.tools.smali.dexlib2.base.reference.BaseMethodHandleReference;
+import com.android.tools.smali.dexlib2.base.reference.BaseMethodProtoReference;
 import com.android.tools.smali.dexlib2.base.reference.BaseTypeReference;
+import com.android.tools.smali.dexlib2.base.value.BaseFieldEncodedValue;
+import com.android.tools.smali.dexlib2.base.value.BaseMethodEncodedValue;
+import com.android.tools.smali.dexlib2.base.value.BaseMethodHandleEncodedValue;
+import com.android.tools.smali.dexlib2.base.value.BaseMethodTypeEncodedValue;
+import com.android.tools.smali.dexlib2.base.value.BaseTypeEncodedValue;
+import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
+import com.android.tools.smali.dexlib2.iface.reference.Reference;
 import com.android.tools.smali.dexlib2.iface.reference.TypeReference;
+import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
+import com.android.tools.smali.dexlib2.iface.value.FieldEncodedValue;
+import com.android.tools.smali.dexlib2.iface.value.MethodEncodedValue;
+import com.android.tools.smali.dexlib2.iface.value.MethodHandleEncodedValue;
+import com.android.tools.smali.dexlib2.iface.value.MethodTypeEncodedValue;
+import com.android.tools.smali.dexlib2.iface.value.TypeEncodedValue;
+import com.google.common.base.Function;
+import com.google.common.collect.Lists;
 
 import java.util.AbstractList;
 import java.util.AbstractSet;
@@ -116,6 +139,119 @@
             }
         };
     }
+
+    @Nonnull public static MethodHandleReference rewriteMethodHandleReference(
+            @Nonnull final Rewriters rewriters,
+            @Nonnull final MethodHandleReference methodHandleReference) {
+        switch (methodHandleReference.getMethodHandleType()) {
+            case MethodHandleType.STATIC_PUT:
+            case MethodHandleType.STATIC_GET:
+            case MethodHandleType.INSTANCE_PUT:
+            case MethodHandleType.INSTANCE_GET:
+                return new BaseMethodHandleReference() {
+                    @Override public int getMethodHandleType() {
+                        return methodHandleReference.getMethodHandleType();
+                    }
+
+                    @Nonnull @Override public Reference getMemberReference() {
+                        return rewriters.getFieldReferenceRewriter().rewrite((FieldReference)methodHandleReference.getMemberReference());
+                    }
+                };
+            case MethodHandleType.INVOKE_STATIC:
+            case MethodHandleType.INVOKE_INSTANCE:
+            case MethodHandleType.INVOKE_CONSTRUCTOR:
+            case MethodHandleType.INVOKE_DIRECT:
+            case MethodHandleType.INVOKE_INTERFACE:
+                return new BaseMethodHandleReference() {
+                    @Override public int getMethodHandleType() {
+                        return methodHandleReference.getMethodHandleType();
+                    }
+
+                    @Nonnull @Override public Reference getMemberReference() {
+                        return rewriters.getMethodReferenceRewriter().rewrite((MethodReference)methodHandleReference.getMemberReference());
+                    }
+                };
+            default:
+                throw new ExceptionWithContext("Invalid method handle type: %d",
+                        methodHandleReference.getMethodHandleType());
+        }
+    }
+
+    @Nonnull public static MethodProtoReference rewriteMethodProtoReference(
+            @Nonnull final Rewriter<String> typeRewriter,
+            @Nonnull final MethodProtoReference methodProtoReference) {
+        return new BaseMethodProtoReference() {
+            @Nonnull @Override public List<? extends CharSequence> getParameterTypes() {
+                return rewriteList(typeRewriter,
+                        Lists.transform(methodProtoReference.getParameterTypes(),
+                        new Function<CharSequence, String>() {
+                            @Nonnull @Override public String apply(CharSequence input) {
+                                return input.toString();
+                            }
+                        }));
+            }
+
+            @Nonnull @Override public String getReturnType() {
+                return typeRewriter.rewrite(methodProtoReference.getReturnType());
+            }
+        };
+    }
+
+    @Nonnull public static EncodedValue rewriteValue(
+            @Nonnull final Rewriters rewriters,
+            @Nonnull final EncodedValue encodedValue) {
+        switch (encodedValue.getValueType()) {
+            case ValueType.INT:
+            case ValueType.FLOAT:
+            case ValueType.LONG:
+            case ValueType.DOUBLE:
+            case ValueType.STRING:
+                return encodedValue;
+
+            case ValueType.METHOD_TYPE:
+                return new BaseMethodTypeEncodedValue () {
+                    @Override @Nonnull public MethodProtoReference getValue() {
+                        return rewriteMethodProtoReference(
+                            rewriters.getTypeRewriter(),
+                            ((MethodTypeEncodedValue) encodedValue).getValue());
+                    }
+                };
+
+            case ValueType.METHOD_HANDLE:
+                return new BaseMethodHandleEncodedValue () {
+                    @Override @Nonnull public MethodHandleReference getValue() {
+                        return rewriteMethodHandleReference(
+                            rewriters,
+                            ((MethodHandleEncodedValue) encodedValue).getValue());
+                    }
+                };
+
+            case ValueType.TYPE:
+                return new BaseTypeEncodedValue () {
+                    @Override @Nonnull public String getValue() {
+                        return rewriters.getTypeRewriter().rewrite(((TypeEncodedValue) encodedValue).getValue());
+                    }
+                };
+
+            case ValueType.FIELD:
+                return new BaseFieldEncodedValue () {
+                    @Override @Nonnull public FieldReference getValue() {
+                        return rewriters.getFieldReferenceRewriter().rewrite(((FieldEncodedValue) encodedValue).getValue());
+                    }
+                };
+
+            case ValueType.METHOD:
+                return new BaseMethodEncodedValue () {
+                    @Override @Nonnull public MethodReference getValue() {
+                        return rewriters.getMethodReferenceRewriter().rewrite(((MethodEncodedValue) encodedValue).getValue());
+                    }
+                };
+
+            default:
+                throw new ExceptionWithContext("Unsupported encoded value type: %d",
+                        encodedValue.getValueType());
+        }
+    }
 }
 
 
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/Rewriters.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/Rewriters.java
index bb4cd34..93d9cc4 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/Rewriters.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/rewriter/Rewriters.java
@@ -42,6 +42,7 @@
 import com.android.tools.smali.dexlib2.iface.TryBlock;
 import com.android.tools.smali.dexlib2.iface.debug.DebugItem;
 import com.android.tools.smali.dexlib2.iface.instruction.Instruction;
+import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
 import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
 import com.android.tools.smali.dexlib2.iface.value.EncodedValue;
@@ -64,6 +65,7 @@
     @Nonnull Rewriter<String> getTypeRewriter();
     @Nonnull Rewriter<FieldReference> getFieldReferenceRewriter();
     @Nonnull Rewriter<MethodReference> getMethodReferenceRewriter();
+    @Nonnull Rewriter<CallSiteReference> getCallSiteReferenceRewriter();
 
     @Nonnull Rewriter<Annotation> getAnnotationRewriter();
     @Nonnull Rewriter<AnnotationElement> getAnnotationElementRewriter();
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/Preconditions.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/Preconditions.java
index 66c7c40..57faad6 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/Preconditions.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/util/Preconditions.java
@@ -35,7 +35,10 @@
 import com.android.tools.smali.dexlib2.ReferenceType;
 import com.android.tools.smali.dexlib2.VerificationError;
 import com.android.tools.smali.dexlib2.iface.instruction.SwitchElement;
+import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
 import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
 import com.android.tools.smali.dexlib2.iface.reference.Reference;
 import com.android.tools.smali.dexlib2.iface.reference.StringReference;
@@ -274,6 +277,21 @@
                     throw new IllegalArgumentException("Invalid reference type, expecting a method reference");
                 }
                 break;
+            case ReferenceType.METHOD_PROTO:
+                if (!(reference instanceof MethodProtoReference)) {
+                    throw new IllegalArgumentException("Invalid reference type, expecting a method proto reference");
+                }
+                break;
+            case ReferenceType.METHOD_HANDLE:
+                if (!(reference instanceof MethodHandleReference)) {
+                    throw new IllegalArgumentException("Invalid reference type, expecting a method handle reference");
+                }
+                break;
+            case ReferenceType.CALL_SITE:
+                if (!(reference instanceof CallSiteReference)) {
+                    throw new IllegalArgumentException("Invalid reference type, expecting a call site reference");
+                }
+                break;
             default:
                 throw new IllegalArgumentException(String.format("Not a valid reference type: %d", referenceType));
         }
diff --git a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java
index bf35aa9..a6a6fbb 100644
--- a/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java
+++ b/dexlib2/src/main/java/com/android/tools/smali/dexlib2/writer/pool/ClassPool.java
@@ -49,6 +49,7 @@
 import com.android.tools.smali.dexlib2.iface.debug.StartLocal;
 import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference;
 import com.android.tools.smali.dexlib2.iface.reference.FieldReference;
+import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference;
 import com.android.tools.smali.dexlib2.iface.reference.MethodReference;
 import com.android.tools.smali.dexlib2.iface.reference.Reference;
@@ -196,6 +197,9 @@
             case ReferenceType.METHOD_PROTO:
                 dexPool.protoSection.intern((MethodProtoReference)reference);
                 break;
+            case ReferenceType.METHOD_HANDLE:
+                dexPool.methodHandleSection.intern((MethodHandleReference) reference);
+                break;
             case ReferenceType.CALL_SITE:
                 dexPool.callSiteSection.intern((CallSiteReference) reference);
                 break;