MethodHandleItem.java revision 766a678339e615d7e0b3935111392b7eef50df24
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.dx.dex.file; 17 18import com.android.dx.rop.cst.Constant; 19import com.android.dx.rop.cst.CstBaseMethodRef; 20import com.android.dx.rop.cst.CstFieldRef; 21import com.android.dx.rop.cst.CstInterfaceMethodRef; 22import com.android.dx.rop.cst.CstMethodHandle; 23import com.android.dx.util.AnnotatedOutput; 24import com.android.dx.util.Hex; 25 26/** 27 * Representation of a method handle in a DEX file. 28 */ 29public final class MethodHandleItem extends IndexedItem { 30 31 /** The item size when placed in a DEX file. */ 32 private final int ITEM_SIZE = 8; 33 34 /** {@code non-null;} The method handle represented by this item. */ 35 private final CstMethodHandle methodHandle; 36 37 /** 38 * Constructs an instance. 39 * 40 * @param methodHandle {@code non-null;} The method handle to represent in the DEX file. 41 */ 42 public MethodHandleItem(CstMethodHandle methodHandle) { 43 this.methodHandle = methodHandle; 44 } 45 46 /** {@inheritDoc} */ 47 @Override 48 public ItemType itemType() { 49 return ItemType.TYPE_METHOD_HANDLE_ITEM; 50 } 51 52 /** {@inheritDoc} */ 53 @Override 54 public int writeSize() { 55 return ITEM_SIZE; 56 } 57 58 /** {@inheritDoc} */ 59 @Override 60 public void addContents(DexFile file) { 61 MethodHandlesSection methodHandles = file.getMethodHandles(); 62 methodHandles.intern(methodHandle); 63 } 64 65 /** {@inheritDoc} */ 66 @Override 67 public void writeTo(DexFile file, AnnotatedOutput out) { 68 int targetIndex = getTargetIndex(file); 69 if (out.annotates()) { 70 out.annotate(2, "kind: " + Hex.u2(methodHandle.getMethodHandleType())); 71 out.annotate(2, "reserved:" + Hex.u2(0)); 72 if (methodHandle.isAccessor()) { 73 out.annotate(2, "fieldId: " + targetIndex); 74 } else { 75 out.annotate(2, "methodId: " + targetIndex); 76 } 77 out.annotate(2, "reserved:" + Hex.u2(0)); 78 } 79 out.writeShort(methodHandle.getMethodHandleType()); 80 out.writeShort(0); 81 out.writeShort(getTargetIndex(file)); 82 out.writeShort(0); 83 } 84 85 private int getTargetIndex(DexFile file) { 86 Constant ref = methodHandle.getRef(); 87 if (methodHandle.isAccessor()) { 88 FieldIdsSection fieldIds = file.getFieldIds(); 89 return fieldIds.indexOf((CstFieldRef) ref); 90 } else if (methodHandle.isInvocation()) { 91 if (ref instanceof CstInterfaceMethodRef) { 92 ref = ((CstInterfaceMethodRef)ref).toMethodRef(); 93 } 94 MethodIdsSection methodIds = file.getMethodIds(); 95 return methodIds.indexOf((CstBaseMethodRef) ref); 96 } else { 97 throw new IllegalStateException("Unhandled invocation type"); 98 } 99 } 100} 101