xref: /aosp_15_r20/dalvik/dx/src/com/android/dex/MethodHandle.java (revision 055d459012065f78d96b68be8421640240ddf631)
1*055d4590SKeyi Gui /*
2*055d4590SKeyi Gui  * Copyright (C) 2017 The Android Open Source Project
3*055d4590SKeyi Gui  *
4*055d4590SKeyi Gui  * Licensed under the Apache License, Version 2.0 (the "License");
5*055d4590SKeyi Gui  * you may not use this file except in compliance with the License.
6*055d4590SKeyi Gui  * You may obtain a copy of the License at
7*055d4590SKeyi Gui  *
8*055d4590SKeyi Gui  *      http://www.apache.org/licenses/LICENSE-2.0
9*055d4590SKeyi Gui  *
10*055d4590SKeyi Gui  * Unless required by applicable law or agreed to in writing, software
11*055d4590SKeyi Gui  * distributed under the License is distributed on an "AS IS" BASIS,
12*055d4590SKeyi Gui  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*055d4590SKeyi Gui  * See the License for the specific language governing permissions and
14*055d4590SKeyi Gui  * limitations under the License.
15*055d4590SKeyi Gui  */
16*055d4590SKeyi Gui 
17*055d4590SKeyi Gui package com.android.dex;
18*055d4590SKeyi Gui 
19*055d4590SKeyi Gui import com.android.dex.Dex.Section;
20*055d4590SKeyi Gui import com.android.dex.util.Unsigned;
21*055d4590SKeyi Gui 
22*055d4590SKeyi Gui /**
23*055d4590SKeyi Gui  * A method_handle_item:
24*055d4590SKeyi Gui  * https://source.android.com/devices/tech/dalvik/dex-format#method-handle-item
25*055d4590SKeyi Gui  */
26*055d4590SKeyi Gui public class MethodHandle implements Comparable<MethodHandle> {
27*055d4590SKeyi Gui 
28*055d4590SKeyi Gui     /**
29*055d4590SKeyi Gui      * A method handle type code:
30*055d4590SKeyi Gui      * https://source.android.com/devices/tech/dalvik/dex-format#method-handle-type-codes
31*055d4590SKeyi Gui      */
32*055d4590SKeyi Gui     public enum MethodHandleType {
33*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_STATIC_PUT(0x00),
34*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_STATIC_GET(0x01),
35*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INSTANCE_PUT(0x02),
36*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INSTANCE_GET(0x03),
37*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INVOKE_STATIC(0x04),
38*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INVOKE_INSTANCE(0x05),
39*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INVOKE_DIRECT(0x06),
40*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INVOKE_CONSTRUCTOR(0x07),
41*055d4590SKeyi Gui         METHOD_HANDLE_TYPE_INVOKE_INTERFACE(0x08);
42*055d4590SKeyi Gui 
43*055d4590SKeyi Gui         private final int value;
44*055d4590SKeyi Gui 
MethodHandleType(int value)45*055d4590SKeyi Gui         MethodHandleType(int value) {
46*055d4590SKeyi Gui             this.value = value;
47*055d4590SKeyi Gui         }
48*055d4590SKeyi Gui 
fromValue(int value)49*055d4590SKeyi Gui         static MethodHandleType fromValue(int value) {
50*055d4590SKeyi Gui             for (MethodHandleType methodHandleType : values()) {
51*055d4590SKeyi Gui                 if (methodHandleType.value == value) {
52*055d4590SKeyi Gui                     return methodHandleType;
53*055d4590SKeyi Gui                 }
54*055d4590SKeyi Gui             }
55*055d4590SKeyi Gui             throw new IllegalArgumentException(String.valueOf(value));
56*055d4590SKeyi Gui         }
57*055d4590SKeyi Gui 
isField()58*055d4590SKeyi Gui         public boolean isField() {
59*055d4590SKeyi Gui             switch (this) {
60*055d4590SKeyi Gui                 case METHOD_HANDLE_TYPE_STATIC_PUT:
61*055d4590SKeyi Gui                 case METHOD_HANDLE_TYPE_STATIC_GET:
62*055d4590SKeyi Gui                 case METHOD_HANDLE_TYPE_INSTANCE_PUT:
63*055d4590SKeyi Gui                 case METHOD_HANDLE_TYPE_INSTANCE_GET:
64*055d4590SKeyi Gui                     return true;
65*055d4590SKeyi Gui                 default:
66*055d4590SKeyi Gui                     return false;
67*055d4590SKeyi Gui             }
68*055d4590SKeyi Gui         }
69*055d4590SKeyi Gui     }
70*055d4590SKeyi Gui 
71*055d4590SKeyi Gui     private final Dex dex;
72*055d4590SKeyi Gui     private final MethodHandleType methodHandleType;
73*055d4590SKeyi Gui     private final int unused1;
74*055d4590SKeyi Gui     private final int fieldOrMethodId;
75*055d4590SKeyi Gui     private final int unused2;
76*055d4590SKeyi Gui 
MethodHandle( Dex dex, MethodHandleType methodHandleType, int unused1, int fieldOrMethodId, int unused2)77*055d4590SKeyi Gui     public MethodHandle(
78*055d4590SKeyi Gui             Dex dex,
79*055d4590SKeyi Gui             MethodHandleType methodHandleType,
80*055d4590SKeyi Gui             int unused1,
81*055d4590SKeyi Gui             int fieldOrMethodId,
82*055d4590SKeyi Gui             int unused2) {
83*055d4590SKeyi Gui         this.dex = dex;
84*055d4590SKeyi Gui         this.methodHandleType = methodHandleType;
85*055d4590SKeyi Gui         this.unused1 = unused1;
86*055d4590SKeyi Gui         this.fieldOrMethodId = fieldOrMethodId;
87*055d4590SKeyi Gui         this.unused2 = unused2;
88*055d4590SKeyi Gui     }
89*055d4590SKeyi Gui 
90*055d4590SKeyi Gui     @Override
compareTo(MethodHandle o)91*055d4590SKeyi Gui     public int compareTo(MethodHandle o) {
92*055d4590SKeyi Gui         if (methodHandleType != o.methodHandleType) {
93*055d4590SKeyi Gui             return methodHandleType.compareTo(o.methodHandleType);
94*055d4590SKeyi Gui         }
95*055d4590SKeyi Gui         return Unsigned.compare(fieldOrMethodId, o.fieldOrMethodId);
96*055d4590SKeyi Gui     }
97*055d4590SKeyi Gui 
getMethodHandleType()98*055d4590SKeyi Gui     public MethodHandleType getMethodHandleType() {
99*055d4590SKeyi Gui         return methodHandleType;
100*055d4590SKeyi Gui     }
101*055d4590SKeyi Gui 
getUnused1()102*055d4590SKeyi Gui     public int getUnused1() {
103*055d4590SKeyi Gui         return unused1;
104*055d4590SKeyi Gui     }
105*055d4590SKeyi Gui 
getFieldOrMethodId()106*055d4590SKeyi Gui     public int getFieldOrMethodId() {
107*055d4590SKeyi Gui         return fieldOrMethodId;
108*055d4590SKeyi Gui     }
109*055d4590SKeyi Gui 
getUnused2()110*055d4590SKeyi Gui     public int getUnused2() {
111*055d4590SKeyi Gui         return unused2;
112*055d4590SKeyi Gui     }
113*055d4590SKeyi Gui 
writeTo(Section out)114*055d4590SKeyi Gui     public void writeTo(Section out) {
115*055d4590SKeyi Gui         out.writeUnsignedShort(methodHandleType.value);
116*055d4590SKeyi Gui         out.writeUnsignedShort(unused1);
117*055d4590SKeyi Gui         out.writeUnsignedShort(fieldOrMethodId);
118*055d4590SKeyi Gui         out.writeUnsignedShort(unused2);
119*055d4590SKeyi Gui     }
120*055d4590SKeyi Gui 
121*055d4590SKeyi Gui     @Override
toString()122*055d4590SKeyi Gui     public String toString() {
123*055d4590SKeyi Gui         if (dex == null) {
124*055d4590SKeyi Gui             return methodHandleType + " " + fieldOrMethodId;
125*055d4590SKeyi Gui         }
126*055d4590SKeyi Gui         return methodHandleType
127*055d4590SKeyi Gui                 + " "
128*055d4590SKeyi Gui                 + (methodHandleType.isField()
129*055d4590SKeyi Gui                         ? dex.fieldIds().get(fieldOrMethodId)
130*055d4590SKeyi Gui                         : dex.methodIds().get(fieldOrMethodId));
131*055d4590SKeyi Gui     }
132*055d4590SKeyi Gui }
133