auto import from //depot/cupcake/@135843
diff --git a/vm/oo/Object.c b/vm/oo/Object.c
new file mode 100644
index 0000000..189ad09
--- /dev/null
+++ b/vm/oo/Object.c
@@ -0,0 +1,653 @@
+/*
+ * 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.
+ */
+
+/*
+ * Operations on an Object.
+ */
+#include "Dalvik.h"
+
+/*
+ * Find a matching field, in the current class only.
+ *
+ * Returns NULL if the field can't be found.  (Does not throw an exception.)
+ */
+InstField* dvmFindInstanceField(const ClassObject* clazz,
+    const char* fieldName, const char* signature)
+{
+    InstField* pField;
+    int i;
+
+    assert(clazz != NULL);
+
+    /*
+     * Find a field with a matching name and signature.  The Java programming
+     * language does not allow you to have two fields with the same name
+     * and different types, but the Java VM spec does allow it, so we can't
+     * bail out early when the name matches.
+     */
+    pField = clazz->ifields;
+    for (i = 0; i < clazz->ifieldCount; i++, pField++) {
+        if (strcmp(fieldName, pField->field.name) == 0 &&
+            strcmp(signature, pField->field.signature) == 0)
+        {
+            return pField;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Find a matching field, in this class or a superclass.
+ *
+ * Searching through interfaces isn't necessary, because interface fields
+ * are inherently public/static/final.
+ *
+ * Returns NULL if the field can't be found.  (Does not throw an exception.)
+ */
+InstField* dvmFindInstanceFieldHier(const ClassObject* clazz,
+    const char* fieldName, const char* signature)
+{
+    InstField* pField;
+
+    /*
+     * Search for a match in the current class.
+     */
+    pField = dvmFindInstanceField(clazz, fieldName, signature);
+    if (pField != NULL)
+        return pField;
+
+    if (clazz->super != NULL)
+        return dvmFindInstanceFieldHier(clazz->super, fieldName, signature);
+    else
+        return NULL;
+}
+
+
+/*
+ * Find a matching field, in this class or an interface.
+ *
+ * Returns NULL if the field can't be found.  (Does not throw an exception.)
+ */
+StaticField* dvmFindStaticField(const ClassObject* clazz,
+    const char* fieldName, const char* signature)
+{
+    StaticField* pField;
+    int i;
+
+    assert(clazz != NULL);
+
+    pField = clazz->sfields;
+    for (i = 0; i < clazz->sfieldCount; i++, pField++) {
+        if (strcmp(fieldName, pField->field.name) == 0) {
+            /*
+             * The name matches.  Unlike methods, we can't have two fields
+             * with the same names but differing types.
+             */
+            if (strcmp(signature, pField->field.signature) != 0) {
+                LOGW("Found field '%s', but sig is '%s' not '%s'\n",
+                    fieldName, pField->field.signature, signature);
+                return NULL;
+            }
+            return pField;
+        }
+    }
+
+    return NULL;
+}
+
+/*
+ * Find a matching field, in this class or a superclass.
+ *
+ * Returns NULL if the field can't be found.  (Does not throw an exception.)
+ */
+StaticField* dvmFindStaticFieldHier(const ClassObject* clazz,
+    const char* fieldName, const char* signature)
+{
+    StaticField* pField;
+
+    /*
+     * Search for a match in the current class.
+     */
+    pField = dvmFindStaticField(clazz, fieldName, signature);
+    if (pField != NULL)
+        return pField;
+
+    /*
+     * See if it's in any of our interfaces.  We don't check interfaces
+     * inherited from the superclass yet.
+     *
+     * (Note the set may have been stripped down because of redundancy with
+     * the superclass; see notes in createIftable.)
+     */
+    int i = 0;
+    if (clazz->super != NULL) {
+        assert(clazz->iftableCount >= clazz->super->iftableCount);
+        i = clazz->super->iftableCount;
+    }
+    for ( ; i < clazz->iftableCount; i++) {
+        ClassObject* iface = clazz->iftable[i].clazz;
+        pField = dvmFindStaticField(iface, fieldName, signature);
+        if (pField != NULL)
+            return pField;
+    }
+
+    if (clazz->super != NULL)
+        return dvmFindStaticFieldHier(clazz->super, fieldName, signature);
+    else
+        return NULL;
+}
+
+/*
+ * Compare the given name, return type, and argument types with the contents
+ * of the given method. This returns 0 if they are equal and non-zero if not.
+ */
+static inline int compareMethodHelper(Method* method, const char* methodName,
+    const char* returnType, size_t argCount, const char** argTypes)
+{
+    DexParameterIterator iterator;
+    const DexProto* proto;
+
+    if (strcmp(methodName, method->name) != 0) {
+        return 1;
+    }
+
+    proto = &method->prototype;
+        
+    if (strcmp(returnType, dexProtoGetReturnType(proto)) != 0) {
+        return 1;
+    }
+
+    if (dexProtoGetParameterCount(proto) != argCount) {
+        return 1;
+    }
+
+    dexParameterIteratorInit(&iterator, proto);
+
+    for (/*argCount*/; argCount != 0; argCount--, argTypes++) {
+        const char* argType = *argTypes;
+        const char* paramType = dexParameterIteratorNextDescriptor(&iterator);
+
+        if (paramType == NULL) {
+            /* Param list ended early; no match */
+            break;
+        } else if (strcmp(argType, paramType) != 0) {
+            /* Types aren't the same; no match. */
+            break;
+        }
+    }
+
+    if (argCount == 0) {
+        /* We ran through all the given arguments... */
+        if (dexParameterIteratorNextDescriptor(&iterator) == NULL) {
+            /* ...and through all the method's arguments; success! */
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
+/*
+ * Get the count of arguments in the given method descriptor string,
+ * and also find a pointer to the return type.
+ */
+static inline size_t countArgsAndFindReturnType(const char* descriptor,
+    const char** pReturnType) 
+{
+    size_t count = 0;
+    bool bogus = false;
+    bool done = false;
+
+    assert(*descriptor == '(');
+    descriptor++;
+    
+    while (!done) {
+        switch (*descriptor) {
+            case 'B': case 'C': case 'D': case 'F':
+            case 'I': case 'J': case 'S': case 'Z': {
+                count++;
+                break;
+            }
+            case '[': {
+                do {
+                    descriptor++;
+                } while (*descriptor == '[');
+                /*
+                 * Don't increment count, as it will be taken care of
+                 * by the next iteration. Also, decrement descriptor
+                 * to compensate for the increment below the switch.
+                 */
+                descriptor--;
+                break;
+            }
+            case 'L': {
+                do {
+                    descriptor++;
+                } while ((*descriptor != ';') && (*descriptor != '\0'));
+                count++;
+                if (*descriptor == '\0') {
+                    /* Bogus descriptor. */
+                    done = true;
+                    bogus = true;
+                }
+                break;
+            }
+            case ')': {
+                /* 
+                 * Note: The loop will exit after incrementing descriptor
+                 * one more time, so it then points at the return type.
+                 */
+                done = true;
+                break;
+            }
+            default: {
+                /* Bogus descriptor. */
+                done = true;
+                bogus = true;
+                break;
+            }
+        }
+
+        descriptor++;
+    }
+
+    if (bogus) {
+        *pReturnType = NULL;
+        return 0;
+    }
+
+    *pReturnType = descriptor;
+    return count;
+}
+
+/*
+ * Copy the argument types into the given array using the given buffer
+ * for the contents.
+ */
+static inline void copyTypes(char* buffer, const char** argTypes,
+    size_t argCount, const char* descriptor)
+{
+    size_t i;
+    char c;
+
+    /* Skip the '('. */
+    descriptor++;
+    
+    for (i = 0; i < argCount; i++) {
+        argTypes[i] = buffer;
+
+        /* Copy all the array markers and one extra character. */
+        do {
+            c = *(descriptor++);
+            *(buffer++) = c;
+        } while (c == '[');
+
+        if (c == 'L') {
+            /* Copy the rest of a class name. */
+            do {
+                c = *(descriptor++);
+                *(buffer++) = c;
+            } while (c != ';');
+        }
+        
+        *(buffer++) = '\0';
+    }        
+}
+
+/*
+ * Look for a match in the given class. Returns the match if found
+ * or NULL if not.
+ */
+static Method* findMethodInListByDescriptor(const ClassObject* clazz,
+    bool findVirtual, bool isHier, const char* name, const char* descriptor)
+{
+    const char* returnType;
+    size_t argCount = countArgsAndFindReturnType(descriptor, &returnType);
+
+    if (returnType == NULL) {
+        LOGW("Bogus method descriptor: %s\n", descriptor);
+        return NULL;
+    }
+
+    /*
+     * Make buffer big enough for all the argument type characters and
+     * one '\0' per argument. The "- 2" is because "returnType -
+     * descriptor" includes two parens.
+     */
+    char buffer[argCount + (returnType - descriptor) - 2];
+    const char* argTypes[argCount];
+
+    copyTypes(buffer, argTypes, argCount, descriptor);
+
+    while (clazz != NULL) {
+        Method* methods;
+        size_t methodCount;
+        size_t i;
+
+        if (findVirtual) {
+            methods = clazz->virtualMethods;
+            methodCount = clazz->virtualMethodCount;
+        } else {
+            methods = clazz->directMethods;
+            methodCount = clazz->directMethodCount;
+        }
+        
+        for (i = 0; i < methodCount; i++) {
+            Method* method = &methods[i];
+            if (compareMethodHelper(method, name, returnType, argCount,
+                            argTypes) == 0) {
+                return method;
+            }
+        }
+
+        if (! isHier) {
+            break;
+        }
+
+        clazz = clazz->super;
+    }
+
+    return NULL;
+}
+
+/*
+ * Look for a match in the given clazz. Returns the match if found
+ * or NULL if not.
+ */
+static Method* findMethodInListByProto(const ClassObject* clazz,
+    bool findVirtual, bool isHier, const char* name, const DexProto* proto)
+{    
+    while (clazz != NULL) {
+        Method* methods;
+        size_t methodCount;
+        size_t i;
+
+        if (findVirtual) {
+            methods = clazz->virtualMethods;
+            methodCount = clazz->virtualMethodCount;
+        } else {
+            methods = clazz->directMethods;
+            methodCount = clazz->directMethodCount;
+        }
+
+        for (i = 0; i < methodCount; i++) {
+            Method* method = &methods[i];
+            if (dvmCompareNameProtoAndMethod(name, proto, method) == 0) {
+                return method;
+            }
+        }
+
+        if (! isHier) {
+            break;
+        }
+
+        clazz = clazz->super;
+    }
+
+    return NULL;
+}
+
+/*
+ * Find a "virtual" method in a class.
+ *
+ * Does not chase into the superclass.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindVirtualMethodByDescriptor(const ClassObject* clazz,
+    const char* methodName, const char* descriptor)
+{
+    return findMethodInListByDescriptor(clazz, true, false,
+            methodName, descriptor);
+
+    // TODO? - throw IncompatibleClassChangeError if a match is
+    // found in the directMethods list, rather than NotFoundError.
+    // Note we could have been called by dvmFindVirtualMethodHier though.
+}
+
+
+/*
+ * Find a "virtual" method in a class, knowing only the name.  This is
+ * only useful in limited circumstances, e.g. when searching for a member
+ * of an annotation class.
+ *
+ * Does not chase into the superclass.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindVirtualMethodByName(const ClassObject* clazz,
+    const char* methodName)
+{
+    Method* methods = clazz->virtualMethods;
+    int methodCount = clazz->virtualMethodCount;
+    int i;
+
+    for (i = 0; i < methodCount; i++) {
+        if (strcmp(methods[i].name, methodName) == 0)
+            return &methods[i];
+    }
+
+    return NULL;
+}
+
+/*
+ * Find a "virtual" method in a class.
+ *
+ * Does not chase into the superclass.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindVirtualMethod(const ClassObject* clazz, const char* methodName,
+    const DexProto* proto)
+{
+    return findMethodInListByProto(clazz, true, false, methodName, proto);
+}
+
+/*
+ * Find a "virtual" method in a class.  If we don't find it, try the
+ * superclass.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindVirtualMethodHierByDescriptor(const ClassObject* clazz,
+    const char* methodName, const char* descriptor)
+{
+    return findMethodInListByDescriptor(clazz, true, true,
+            methodName, descriptor);
+}
+
+/*
+ * Find a "virtual" method in a class.  If we don't find it, try the
+ * superclass.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindVirtualMethodHier(const ClassObject* clazz,
+    const char* methodName, const DexProto* proto)
+{
+    return findMethodInListByProto(clazz, true, true, methodName, proto);
+}
+
+/*
+ * Find a "direct" method (static, private, or "<*init>").
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindDirectMethodByDescriptor(const ClassObject* clazz,
+    const char* methodName, const char* descriptor)
+{
+    return findMethodInListByDescriptor(clazz, false, false,
+            methodName, descriptor);
+}
+
+/*
+ * Find a "direct" method.  If we don't find it, try the superclass.  This
+ * is only appropriate for static methods, but will work for all direct
+ * methods.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindDirectMethodHierByDescriptor(const ClassObject* clazz,
+    const char* methodName, const char* descriptor)
+{
+    return findMethodInListByDescriptor(clazz, false, true,
+            methodName, descriptor);
+}
+
+/*
+ * Find a "direct" method (static or "<*init>").
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindDirectMethod(const ClassObject* clazz, const char* methodName,
+    const DexProto* proto)
+{
+    return findMethodInListByProto(clazz, false, false, methodName, proto);
+}
+
+/*
+ * Find a "direct" method in a class.  If we don't find it, try the
+ * superclass.
+ *
+ * Returns NULL if the method can't be found.  (Does not throw an exception.)
+ */
+Method* dvmFindDirectMethodHier(const ClassObject* clazz,
+    const char* methodName, const DexProto* proto)
+{
+    return findMethodInListByProto(clazz, false, true, methodName, proto);
+}
+
+/*
+ * We have a method pointer for a method in "clazz", but it might be
+ * pointing to a method in a derived class.  We want to find the actual entry
+ * from the class' vtable.  If "clazz" is an interface, we have to do a
+ * little more digging.
+ *
+ * (This is used for reflection and JNI "call method" calls.)
+ */
+const Method* dvmGetVirtualizedMethod(const ClassObject* clazz,
+    const Method* meth)
+{
+    Method* actualMeth;
+    int methodIndex;
+
+    assert(!dvmIsStaticMethod(meth));
+
+    if (dvmIsPrivateMethod(meth))   // no vtable entry for these
+        return meth;
+
+    /*
+     * If the method was declared in an interface, we need to scan through
+     * the class' list of interfaces for it, and find the vtable index
+     * from that.
+     *
+     * TODO: use the interface cache.
+     */
+    if (dvmIsInterfaceClass(meth->clazz)) {
+        int i;
+
+        for (i = 0; i < clazz->iftableCount; i++) {
+            if (clazz->iftable[i].clazz == meth->clazz)
+                break;
+        }
+        if (i == clazz->iftableCount) {
+            dvmThrowException("Ljava/lang/IncompatibleClassChangeError;",
+                "invoking method from interface not implemented by class");
+            return NULL;
+        }
+
+        methodIndex = clazz->iftable[i].methodIndexArray[meth->methodIndex];
+    } else {
+        methodIndex = meth->methodIndex;
+    }
+
+    assert(methodIndex >= 0 && methodIndex < clazz->vtableCount);
+    actualMeth = clazz->vtable[methodIndex];
+
+    /*
+     * Make sure there's code to execute.
+     */
+    if (dvmIsAbstractMethod(actualMeth)) {
+        dvmThrowException("Ljava/lang/AbstractMethodError;", NULL);
+        return NULL;
+    }
+    assert(!dvmIsMirandaMethod(actualMeth));
+
+    return actualMeth;
+}
+
+/*
+ * Get the source file for a method.
+ */
+const char* dvmGetMethodSourceFile(const Method* meth)
+{
+    /*
+     * TODO: A method's debug info can override the default source
+     * file for a class, so we should account for that possibility
+     * here.
+     */
+    return meth->clazz->sourceFile;
+}
+
+/*
+ * Dump some information about an object.
+ */
+void dvmDumpObject(const Object* obj)
+{
+    ClassObject* clazz;
+    int i;
+
+    if (obj == NULL || obj->clazz == NULL) {
+        LOGW("Null or malformed object not dumped\n");
+        return;
+    }
+
+    clazz = obj->clazz;
+    LOGV("----- Object dump: %p (%s, %d bytes) -----\n",
+        obj, clazz->descriptor, (int) clazz->objectSize);
+    //printHexDump(obj, clazz->objectSize);
+    LOGV("  Fields:\n");
+    for (i = 0; i < clazz->ifieldCount; i++) {
+        const InstField* pField = &clazz->ifields[i];
+        char type = pField->field.signature[0];
+
+        if (type == 'F' || type == 'D') {
+            double dval;
+
+            if (type == 'F')
+                dval = dvmGetFieldFloat(obj, pField->byteOffset);
+            else
+                dval = dvmGetFieldDouble(obj, pField->byteOffset);
+
+            LOGV("  %2d: '%s' '%s' flg=%04x %.3f\n", i, pField->field.name,
+                pField->field.signature, pField->field.accessFlags, dval);
+        } else {
+            long long lval;
+
+            if (pField->field.signature[0] == 'J')
+                lval = dvmGetFieldLong(obj, pField->byteOffset);
+            else if (pField->field.signature[0] == 'Z')
+                lval = dvmGetFieldBoolean(obj, pField->byteOffset);
+            else
+                lval = dvmGetFieldInt(obj, pField->byteOffset);
+
+            LOGV("  %2d: '%s' '%s' af=%04x 0x%llx\n", i, pField->field.name,
+                pField->field.signature, pField->field.accessFlags, lval);
+        }
+    }
+}
+