/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * The VM wraps some additional data structures around the DexFile.  These
 * are defined here.
 */
#ifndef _DALVIK_DVMDEX
#define _DALVIK_DVMDEX

#include "libdex/DexFile.h"

/* extern */
struct ClassObject;
struct HashTable;
struct InstField;
struct Method;
struct StringObject;


/*
 * Some additional VM data structures that are associated with the DEX file.
 */
typedef struct DvmDex {
    /* pointer to the DexFile we're associated with */
    DexFile*            pDexFile;

    /* clone of pDexFile->pHeader (it's used frequently enough) */
    const DexHeader*    pHeader;

    /* interned strings; parallel to "stringIds" */
    struct StringObject** pResStrings;

    /* resolved classes; parallel to "typeIds" */
    struct ClassObject** pResClasses;

    /* resolved methods; parallel to "methodIds" */
    struct Method**     pResMethods;

    /* resolved instance fields; parallel to "fieldIds" */
    /* (this holds both InstField and StaticField) */
    struct Field**      pResFields;

    /* interface method lookup cache */
    struct AtomicCache* pInterfaceCache;

    /* shared memory region with file contents */
    MemMapping          memMap;
} DvmDex;


/*
 * Given a file descriptor for an open "optimized" DEX file, map it into
 * memory and parse the contents.
 *
 * On success, returns 0 and sets "*ppDvmDex" to a newly-allocated DvmDex.
 * On failure, returns a meaningful error code [currently just -1].
 */
int dvmDexFileOpenFromFd(int fd, DvmDex** ppDvmDex);

/*
 * Open a partial DEX file.  Only useful as part of the optimization process.
 */
int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);

/*
 * Free a DvmDex structure, along with any associated structures.
 */
void dvmDexFileFree(DvmDex* pDvmDex);


/*
 * Change the 1- or 2-byte value at the specified address to a new value.  If
 * the location already has the new value, do nothing.
 *
 * This does not make any synchronization guarantees.  The caller must
 * ensure exclusivity vs. other callers.
 *
 * For the 2-byte call, the pointer should have 16-bit alignment.
 *
 * Returns "true" on success.
 */
bool dvmDexChangeDex1(DvmDex* pDvmDex, u1* addr, u1 newVal);
bool dvmDexChangeDex2(DvmDex* pDvmDex, u2* addr, u2 newVal);


#if DVM_RESOLVER_CACHE == DVM_RC_DISABLED
/* 1:1 mapping */

/*
 * Return the requested item if it has been resolved, or NULL if it hasn't.
 */
INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
    u4 stringIdx)
{
    assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
    return pDvmDex->pResStrings[stringIdx];
}
INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
    u4 classIdx)
{
    assert(classIdx < pDvmDex->pHeader->typeIdsSize);
    return pDvmDex->pResClasses[classIdx];
}
INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
    u4 methodIdx)
{
    assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
    return pDvmDex->pResMethods[methodIdx];
}
INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
    u4 fieldIdx)
{
    assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
    return pDvmDex->pResFields[fieldIdx];
}

/*
 * Update the resolved item table.  Resolution always produces the same
 * result, so we're not worried about atomicity here.
 */
INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
    struct StringObject* str)
{
    assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
    pDvmDex->pResStrings[stringIdx] = str;
}
INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
    struct ClassObject* clazz)
{
    assert(classIdx < pDvmDex->pHeader->typeIdsSize);
    pDvmDex->pResClasses[classIdx] = clazz;
}
INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
    struct Method* method)
{
    assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
    pDvmDex->pResMethods[methodIdx] = method;
}
INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
    struct Field* field)
{
    assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
    pDvmDex->pResFields[fieldIdx] = field;
}

#elif DVM_RESOLVER_CACHE == DVM_RC_REDUCING
/* reduce request to fit in a less-than-full-size cache table */

/*
 * Return the requested item if it has been resolved, or NULL if it hasn't.
 *
 * If we have a mapping table defined for this category, but there's no
 * entry for this index, we always return NULL.  Otherwise, we return the
 * entry.  (To regain some performance we may want to assume that the
 * table exists when compiled in this mode -- avoids a null check but
 * prevents us from switching back and forth without rebuilding the VM.)
 *
 * We could save an integer compare here by ensuring that map[kNoIndexMapping]
 * always evalutes to NULL (e.g. set kNoIndexMapping = 0).
 */
INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
    u4 stringIdx)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;

    assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
    if (pIndexMap->stringReducedCount > 0) {
        stringIdx = pIndexMap->stringMap[stringIdx];
        if (stringIdx == kNoIndexMapping)
            return NULL;
    }
    return pDvmDex->pResStrings[stringIdx];
}
INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
    u4 classIdx)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;

    assert(classIdx < pDvmDex->pHeader->typeIdsSize);
    if (pIndexMap->classReducedCount > 0) {
        classIdx = pIndexMap->classMap[classIdx];
        if (classIdx == kNoIndexMapping)
            return NULL;
    }
    return pDvmDex->pResClasses[classIdx];
}
INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
    u4 methodIdx)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;

    assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
    if (pIndexMap->methodReducedCount > 0) {
        methodIdx = pIndexMap->methodMap[methodIdx];
        if (methodIdx == kNoIndexMapping)
            return NULL;
    }
    return pDvmDex->pResMethods[methodIdx];
}
INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
    u4 fieldIdx)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;

    assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
    if (pIndexMap->fieldReducedCount > 0) {
        fieldIdx = pIndexMap->fieldMap[fieldIdx];
        if (fieldIdx == kNoIndexMapping)
            return NULL;
    }
    return pDvmDex->pResFields[fieldIdx];
}

/*
 * Update the resolved item table.  Resolution always produces the same
 * result, so we're not worried about atomicity here.
 */
INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
    struct StringObject* str)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
    u4 newIdx;

    assert(stringIdx < pDvmDex->pHeader->stringIdsSize);
    if (pIndexMap->stringReducedCount > 0) {
        newIdx = pIndexMap->stringMap[stringIdx];
        if (newIdx != kNoIndexMapping)
            pDvmDex->pResStrings[newIdx] = str;
    }
}
INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
    struct ClassObject* clazz)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
    u4 newIdx;

    assert(classIdx < pDvmDex->pHeader->typeIdsSize);
    if (pIndexMap->classReducedCount > 0) {
        newIdx = pIndexMap->classMap[classIdx];
        if (newIdx != kNoIndexMapping)
            pDvmDex->pResClasses[newIdx] = clazz;
    }
}
INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
    struct Method* method)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
    u4 newIdx;

    assert(methodIdx < pDvmDex->pHeader->methodIdsSize);
    if (pIndexMap->methodReducedCount > 0) {
        newIdx = pIndexMap->methodMap[methodIdx];
        if (newIdx != kNoIndexMapping)
            pDvmDex->pResMethods[newIdx] = method;
    }
}
INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
    struct Field* field)
{
    const DexIndexMap* pIndexMap = &pDvmDex->pDexFile->indexMap;
    u4 newIdx;

    assert(fieldIdx < pDvmDex->pHeader->fieldIdsSize);
    if (pIndexMap->fieldReducedCount > 0) {
        newIdx = pIndexMap->fieldMap[fieldIdx];
        if (newIdx != kNoIndexMapping)
            pDvmDex->pResFields[newIdx] = field;
    }
}

#elif DVM_RESOLVER_CACHE == DVM_RC_EXPANDING

#error "not implemented"    /* TODO */

#elif DVM_RESOLVER_CACHE == DVM_RC_NO_CACHE

/*
 * There's no cache, so we always return NULL.
 */
INLINE struct StringObject* dvmDexGetResolvedString(const DvmDex* pDvmDex,
    u4 stringIdx)
{
    return NULL;
}
INLINE struct ClassObject* dvmDexGetResolvedClass(const DvmDex* pDvmDex,
    u4 classIdx)
{
    return NULL;
}
INLINE struct Method* dvmDexGetResolvedMethod(const DvmDex* pDvmDex,
    u4 methodIdx)
{
    return NULL;
}
INLINE struct Field* dvmDexGetResolvedField(const DvmDex* pDvmDex,
    u4 fieldIdx)
{
    return NULL;
}

/*
 * Update the resolved item table.  There is no table, so do nothing.
 */
INLINE void dvmDexSetResolvedString(DvmDex* pDvmDex, u4 stringIdx,
    struct StringObject* str)
{}
INLINE void dvmDexSetResolvedClass(DvmDex* pDvmDex, u4 classIdx,
    struct ClassObject* clazz)
{}
INLINE void dvmDexSetResolvedMethod(DvmDex* pDvmDex, u4 methodIdx,
    struct Method* method)
{}
INLINE void dvmDexSetResolvedField(DvmDex* pDvmDex, u4 fieldIdx,
    struct Field* field)
{}

#else
#error "huh?"
#endif /*DVM_RESOLVER_CACHE==N*/

#endif /*_DALVIK_DVMDEX*/
