1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * instanceof, checkcast, etc.
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <stdlib.h>
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * I think modern C mandates that the results of a boolean expression are
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * 0 or 1.  If not, or we suddenly turn into C++ and bool != int, use this.
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BOOL_TO_INT(x)  (x)
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project//#define BOOL_TO_INT(x)  ((x) ? 1 : 0)
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Number of entries in instanceof cache.  MUST be a power of 2.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define INSTANCEOF_CACHE_SIZE   1024
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Allocate cache.
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
391e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirobool dvmInstanceofStartup()
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    gDvm.instanceofCache = dvmAllocAtomicCache(INSTANCEOF_CACHE_SIZE);
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (gDvm.instanceofCache == NULL)
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Discard the cache.
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
501e1433e78f560a01744e870c19c162ab88df9dc1Carl Shapirovoid dvmInstanceofShutdown()
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    dvmFreeAtomicCache(gDvm.instanceofCache);
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
56f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
57f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether "sub" is an instance of "clazz", where both of these
58f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * are array classes.
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Consider an array class, e.g. Y[][], where Y is a subclass of X.
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Y[][]        --> true (identity)
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof X[][]        --> true (element superclass)
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Y            --> false
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Y[]          --> false
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Object       --> true (everything is an object)
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Object[]     --> true
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Object[][]   --> true
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Object[][][] --> false (too many []s)
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Serializable     --> true (all arrays are Serializable)
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Serializable[]   --> true
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   Y[][] instanceof Serializable[][] --> false (unless Y is Serializable)
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Don't forget about primitive types.
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *   int[] instanceof Object[]     --> false
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "subElemClass" is sub->elementClass.
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "subDim" is usually just sub->dim, but for some kinds of checks we want
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to pass in a non-array class and pretend that it's an array.
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int isArrayInstanceOfArray(const ClassObject* subElemClass, int subDim,
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const ClassObject* clazz)
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //assert(dvmIsArrayClass(sub));
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArrayClass(clazz));
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* "If T is an array type TC[]... one of the following must be true:
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   TC and SC are the same primitive type.
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *   TC and SC are reference types and type SC can be cast to TC [...]."
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * We need the class objects for the array elements.  For speed we
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * tucked them into the class object.
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(subDim > 0 && clazz->arrayDim > 0);
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (subDim == clazz->arrayDim) {
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * See if "sub" is an instance of "clazz".  This handles the
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * interfaces, java.lang.Object, superclassing, etc.
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return dvmInstanceof(subElemClass, clazz->elementClass);
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (subDim > clazz->arrayDim) {
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * The thing we might be an instance of has fewer dimensions.  It
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * must be an Object or array of Object, or a standard array
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * interface or array of standard array interfaces (the standard
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * interfaces being java/lang/Cloneable and java/io/Serializable).
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsInterfaceClass(clazz->elementClass)) {
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * See if the class implements its base element.  We know the
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * base element is an interface; if the array class implements
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * it, we know it's a standard array interface.
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return dvmImplements(clazz, clazz->elementClass);
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } else {
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /*
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * See if this is an array of Object, Object[], etc.  We know
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * that the superclass of an array is always Object, so we
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             * just compare the element type to that.
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             */
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return (clazz->elementClass == clazz->super);
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Too many []s.
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether "sub" is a sub-class of "clazz", where "sub" is an
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * array class.
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "clazz" could be an array class, interface, or simple class.
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int isArrayInstanceOf(const ClassObject* sub, const ClassObject* clazz)
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsArrayClass(sub));
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* "If T is an interface type, T must be one of the interfaces
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * implemented by arrays."
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * I'm not checking that here, because dvmInstanceof tests for
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * interfaces first, and the generic dvmImplements stuff should
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * work correctly.
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(!dvmIsInterfaceClass(clazz));     /* make sure */
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* "If T is a class type, then T must be Object."
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     *
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * The superclass of an array is always java.lang.Object, so just
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * compare against that.
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!dvmIsArrayClass(clazz))
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return BOOL_TO_INT(clazz == sub->super);
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If T is an array type TC[] ...
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return isArrayInstanceOfArray(sub->elementClass, sub->arrayDim, clazz);
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Returns 1 (true) if "clazz" is an implementation of "interface".
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "clazz" could be a class or an interface.
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmImplements(const ClassObject* clazz, const ClassObject* interface)
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(dvmIsInterfaceClass(interface));
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * All interfaces implemented directly and by our superclass, and
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * recursively all super-interfaces of those interfaces, are listed
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * in "iftable", so we can just do a linear scan through that.
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < clazz->iftableCount; i++) {
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (clazz->iftable[i].clazz == interface)
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return 1;
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return 0;
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Determine whether or not we can put an object into an array, based on
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the class hierarchy.  The object might itself by an array, which means
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * we have to pay attention to the array instanceof rules.
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Note that "objectClass" could be an array, but objectClass->elementClass
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is always a non-array type.
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectbool dvmCanPutArrayElement(const ClassObject* objectClass,
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const ClassObject* arrayClass)
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsArrayClass(objectClass)) {
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We're stuffing an array into an array.  We want to see if the
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * elements of "arrayClass" are compatible with "objectClass".
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We bump up the number of dimensions in "objectClass" so that we
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * can compare the two directly.
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isArrayInstanceOfArray(objectClass->elementClass,
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    objectClass->arrayDim + 1, arrayClass);
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * We're putting a non-array element into an array.  We need to
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * test to see if the elements are compatible.  The easiest way
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * to do that is to "arrayify" it and use the standard array
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * compatibility check.
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isArrayInstanceOfArray(objectClass, 1, arrayClass);
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform the instanceof calculation.
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic inline int isInstanceof(const ClassObject* instance,
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const ClassObject* clazz)
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (dvmIsInterfaceClass(clazz)) {
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return dvmImplements(instance, clazz);
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (dvmIsArrayClass(instance)) {
230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return isArrayInstanceOf(instance, clazz);
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return dvmIsSubClass(instance, clazz);
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Do the instanceof calculation, pulling the result from the cache if
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * possible.
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectint dvmInstanceofNonTrivial(const ClassObject* instance,
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const ClassObject* clazz)
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define ATOMIC_CACHE_CALC isInstanceof(instance, clazz)
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return ATOMIC_CACHE_LOOKUP(gDvm.instanceofCache,
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                INSTANCEOF_CACHE_SIZE, instance, clazz);
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#undef ATOMIC_CACHE_CALC
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
249