1 /* 2 * Copyright (C) 2008 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 */ 16 17 /* 18 * Functions for dealing with method prototypes 19 */ 20 21 #ifndef _LIBDEX_DEXPROTO 22 #define _LIBDEX_DEXPROTO 23 24 #include "DexFile.h" 25 26 /* 27 * Single-thread single-string cache. This structure holds a pointer to 28 * a string which is semi-automatically manipulated by some of the 29 * method prototype functions. Functions which use in this struct 30 * generally return a string that is valid until the next 31 * time the same DexStringCache is used. 32 */ 33 typedef struct DexStringCache { 34 char* value; /* the latest value */ 35 size_t allocatedSize; /* size of the allocated buffer, if allocated */ 36 char buffer[120]; /* buffer used to hold small-enough results */ 37 } DexStringCache; 38 39 /* 40 * Initialize the given DexStringCache. Use this function before passing 41 * one into any other function. 42 */ 43 void dexStringCacheInit(DexStringCache* pCache); 44 45 /* 46 * Release the allocated contents of the given DexStringCache, if any. 47 * Use this function after your last use of a DexStringCache. 48 */ 49 void dexStringCacheRelease(DexStringCache* pCache); 50 51 /* 52 * If the given DexStringCache doesn't already point at the given value, 53 * make a copy of it into the cache. This always returns a writable 54 * pointer to the contents (whether or not a copy had to be made). This 55 * function is intended to be used after making a call that at least 56 * sometimes doesn't populate a DexStringCache. 57 */ 58 char* dexStringCacheEnsureCopy(DexStringCache* pCache, const char* value); 59 60 /* 61 * Abandon the given DexStringCache, and return a writable copy of the 62 * given value (reusing the string cache's allocation if possible). 63 * The return value must be free()d by the caller. Use this instead of 64 * dexStringCacheRelease() if you want the buffer to survive past the 65 * scope of the DexStringCache. 66 */ 67 char* dexStringCacheAbandon(DexStringCache* pCache, const char* value); 68 69 /* 70 * Method prototype structure, which refers to a protoIdx in a 71 * particular DexFile. 72 */ 73 typedef struct DexProto { 74 const DexFile* dexFile; /* file the idx refers to */ 75 u4 protoIdx; /* index into proto_ids table of dexFile */ 76 } DexProto; 77 78 /* 79 * Set the given DexProto to refer to the prototype of the given MethodId. 80 */ 81 DEX_INLINE void dexProtoSetFromMethodId(DexProto* pProto, 82 const DexFile* pDexFile, const DexMethodId* pMethodId) 83 { 84 pProto->dexFile = pDexFile; 85 pProto->protoIdx = pMethodId->protoIdx; 86 } 87 88 /* 89 * Get the short-form method descriptor for the given prototype. The 90 * prototype must be protoIdx-based. 91 */ 92 const char* dexProtoGetShorty(const DexProto* pProto); 93 94 /* 95 * Get the full method descriptor for the given prototype. 96 */ 97 const char* dexProtoGetMethodDescriptor(const DexProto* pProto, 98 DexStringCache* pCache); 99 100 /* 101 * Get a copy of the descriptor string associated with the given prototype. 102 * The returned pointer must be free()ed by the caller. 103 */ 104 char* dexProtoCopyMethodDescriptor(const DexProto* pProto); 105 106 /* 107 * Get the parameter descriptors for the given prototype. This is the 108 * concatenation of all the descriptors for all the parameters, in 109 * order, with no other adornment. 110 */ 111 const char* dexProtoGetParameterDescriptors(const DexProto* pProto, 112 DexStringCache* pCache); 113 114 /* 115 * Return the utf-8 encoded descriptor string from the proto of a MethodId. 116 */ 117 DEX_INLINE const char* dexGetDescriptorFromMethodId(const DexFile* pDexFile, 118 const DexMethodId* pMethodId, DexStringCache* pCache) 119 { 120 DexProto proto; 121 122 dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); 123 return dexProtoGetMethodDescriptor(&proto, pCache); 124 } 125 126 /* 127 * Get a copy of the utf-8 encoded method descriptor string from the 128 * proto of a MethodId. The returned pointer must be free()ed by the 129 * caller. 130 */ 131 DEX_INLINE char* dexCopyDescriptorFromMethodId(const DexFile* pDexFile, 132 const DexMethodId* pMethodId) 133 { 134 DexProto proto; 135 136 dexProtoSetFromMethodId(&proto, pDexFile, pMethodId); 137 return dexProtoCopyMethodDescriptor(&proto); 138 } 139 140 /* 141 * Get the type descriptor for the return type of the given prototype. 142 */ 143 const char* dexProtoGetReturnType(const DexProto* pProto); 144 145 /* 146 * Get the parameter count of the given prototype. 147 */ 148 size_t dexProtoGetParameterCount(const DexProto* pProto); 149 150 /* 151 * Compute the number of parameter words (u4 units) required by the 152 * given prototype. For example, if the method takes (int, long) and 153 * returns double, this would return 3 (one for the int, two for the 154 * long, and the return type isn't relevant). 155 */ 156 int dexProtoComputeArgsSize(const DexProto* pProto); 157 158 /* 159 * Compare the two prototypes. The two prototypes are compared 160 * with the return type as the major order, then the first arguments, 161 * then second, etc. If two prototypes are identical except that one 162 * has extra arguments, then the shorter argument is considered the 163 * earlier one in sort order (similar to strcmp()). 164 */ 165 int dexProtoCompare(const DexProto* pProto1, const DexProto* pProto2); 166 167 /* 168 * Compare the two prototypes. The two prototypes are compared 169 * with the first argument as the major order, then second, etc. If two 170 * prototypes are identical except that one has extra arguments, then the 171 * shorter argument is considered the earlier one in sort order (similar 172 * to strcmp()). 173 */ 174 int dexProtoCompareParameters(const DexProto* pProto1, const DexProto* pProto2); 175 176 /* 177 * Compare a prototype and a string method descriptor. The comparison 178 * is done as if the descriptor were converted to a prototype and compared 179 * with dexProtoCompare(). 180 */ 181 int dexProtoCompareToDescriptor(const DexProto* proto, const char* descriptor); 182 183 /* 184 * Single-thread prototype parameter iterator. This structure holds a 185 * pointer to a prototype and its parts, along with a cursor. 186 */ 187 typedef struct DexParameterIterator { 188 const DexProto* proto; 189 const DexTypeList* parameters; 190 int parameterCount; 191 int cursor; 192 } DexParameterIterator; 193 194 /* 195 * Initialize the given DexParameterIterator to be at the start of the 196 * parameters of the given prototype. 197 */ 198 void dexParameterIteratorInit(DexParameterIterator* pIterator, 199 const DexProto* pProto); 200 201 /* 202 * Get the type_id index for the next parameter, if any. This returns 203 * kDexNoIndex if the last parameter has already been consumed. 204 */ 205 u4 dexParameterIteratorNextIndex(DexParameterIterator* pIterator); 206 207 /* 208 * Get the type descriptor for the next parameter, if any. This returns 209 * NULL if the last parameter has already been consumed. 210 */ 211 const char* dexParameterIteratorNextDescriptor( 212 DexParameterIterator* pIterator); 213 214 215 216 #endif /*_LIBDEX_DEXPROTO*/ 217