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/*
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Support for -Xcheck:jni (the "careful" version of the JNI interfaces).
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We want to verify types, make sure class and field IDs are valid, and
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ensure that JNI's semantic expectations are being met.  JNI seems to
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * be relatively lax when it comes to requirements for permission checks,
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * e.g. access to private methods is generally allowed from anywhere.
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: keep a counter on global Get/Release.  Report a warning if some Gets
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * were not Released.  Do not count explicit Add/DeleteGlobalRef calls (or
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * count them separately, so we can complain if they exceed a certain
28f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * threshold).
29f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO: verify that the methodID passed into the Call functions is for
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a method in the specified class.
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "Dalvik.h"
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include "JniInternal.h"
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#include <zlib.h>
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
3859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFaddenstatic void abortMaybe(void);       // fwd
3959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
4059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
4159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
4259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * ===========================================================================
4359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden *      JNI call bridge wrapper
4459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * ===========================================================================
4559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
4659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
4759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
4859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * Check the result of a native method call that returns an object reference.
4959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden *
5059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * The primary goal here is to verify that native code is returning the
5159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * correct type of object.  If it's declared to return a String but actually
5259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * returns a byte array, things will fail in strange ways later on.
5359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden *
5459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * This can be a fairly expensive operation, since we have to look up the
5559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * return type class by name in method->clazz' class loader.  We take a
5659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * shortcut here and allow the call to succeed if the descriptor strings
5759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * match.  This will allow some false-positives when a class is redefined
5859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * by a class loader, but that's rare enough that it doesn't seem worth
5959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * testing for.
600423f0e813a3807168fe5524405eb96675532097Andy McFadden *
610423f0e813a3807168fe5524405eb96675532097Andy McFadden * At this point, pResult->l has already been converted to an object pointer.
6259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
63a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenstatic void checkCallResultCommon(const u4* args, JValue* pResult,
6459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const Method* method, Thread* self)
6559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden{
6659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    assert(pResult->l != NULL);
670423f0e813a3807168fe5524405eb96675532097Andy McFadden    Object* resultObj = (Object*) pResult->l;
68ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* objClazz = resultObj->clazz;
6959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
7059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    /*
7159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden     * Make sure that pResult->l is an instance of the type this
7259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden     * method was expected to return.
7359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden     */
7459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const char* declType = dexProtoGetReturnType(&method->prototype);
7559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const char* objType = objClazz->descriptor;
7659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    if (strcmp(declType, objType) == 0) {
7759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        /* names match; ignore class loader issues and allow it */
7859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        LOGV("Check %s.%s: %s io %s (FAST-OK)\n",
7959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            method->clazz->descriptor, method->name, objType, declType);
8059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    } else {
8159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        /*
8259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * Names didn't match.  We need to resolve declType in the context
8359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * of method->clazz->classLoader, and compare the class objects
8459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * for equality.
8559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         *
8659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * Since we're returning an instance of declType, it's safe to
8759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * assume that it has been loaded and initialized (or, for the case
88ac175b4faa3c3c5cc0298fd30a5b38636eeee596Andy McFadden         * of an array, generated).  However, the current class loader may
89ac175b4faa3c3c5cc0298fd30a5b38636eeee596Andy McFadden         * not be listed as an initiating loader, so we can't just look for
90ac175b4faa3c3c5cc0298fd30a5b38636eeee596Andy McFadden         * it in the loaded-classes list.
9159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         */
9259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        ClassObject* declClazz;
9359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
94ac175b4faa3c3c5cc0298fd30a5b38636eeee596Andy McFadden        declClazz = dvmFindClassNoInit(declType, method->clazz->classLoader);
9559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        if (declClazz == NULL) {
9659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("JNI WARNING: method declared to return '%s' returned '%s'\n",
9759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                declType, objType);
9859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("             failed in %s.%s ('%s' not found)\n",
9959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                method->clazz->descriptor, method->name, declType);
10059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            abortMaybe();
10159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            return;
10259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        }
10359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        if (!dvmInstanceof(objClazz, declClazz)) {
10459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("JNI WARNING: method declared to return '%s' returned '%s'\n",
10559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                declType, objType);
10659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("             failed in %s.%s\n",
10759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                method->clazz->descriptor, method->name);
10859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            abortMaybe();
10959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            return;
11059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        } else {
11159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGV("Check %s.%s: %s io %s (SLOW-OK)\n",
11259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                method->clazz->descriptor, method->name, objType, declType);
11359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        }
11459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    }
11559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden}
11659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
11759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
1180083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * Determine if we need to check the return type coming out of the call.
1190083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden *
120a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * (We don't do this at the top of checkCallResultCommon() because this is on
1210083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * the critical path for native method calls.)
1220083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden */
1230083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenstatic inline bool callNeedsCheck(const u4* args, JValue* pResult,
1240083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    const Method* method, Thread* self)
1250083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden{
1260083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    return (method->shorty[0] == 'L' && !dvmCheckException(self) &&
1270083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden            pResult->l != NULL);
1280083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden}
1290083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden
1300083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden/*
13159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * Check a call into native code.
13259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
1330083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_general(const u4* args, JValue* pResult,
13459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const Method* method, Thread* self)
13559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden{
1360083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_general(args, pResult, method, self);
1370083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
138a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        checkCallResultCommon(args, pResult, method, self);
13959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden}
14059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
14159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
14259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * Check a synchronized call into native code.
14359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
1440083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_synchronized(const u4* args, JValue* pResult,
14559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const Method* method, Thread* self)
14659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden{
1470083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_synchronized(args, pResult, method, self);
1480083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
149a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        checkCallResultCommon(args, pResult, method, self);
1500083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden}
1510083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden
1520083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden/*
1530083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * Check a virtual call with no reference arguments (other than "this").
1540083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden */
1550083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
1560083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    const Method* method, Thread* self)
1570083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden{
1580083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_virtualNoRef(args, pResult, method, self);
1590083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
160a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        checkCallResultCommon(args, pResult, method, self);
1610083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden}
1620083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden
1630083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden/*
1640083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * Check a static call with no reference arguments (other than "clazz").
1650083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden */
1660083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_staticNoRef(const u4* args, JValue* pResult,
1670083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    const Method* method, Thread* self)
1680083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden{
1690083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_staticNoRef(args, pResult, method, self);
1700083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
171a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        checkCallResultCommon(args, pResult, method, self);
17259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden}
17359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
17459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
17559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
17659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * ===========================================================================
17759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden *      JNI function helpers
17859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * ===========================================================================
17959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
18059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define JNI_ENTER()     dvmChangeStatus(NULL, THREAD_RUNNING)
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define JNI_EXIT()      dvmChangeStatus(NULL, THREAD_NATIVE)
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BASE_ENV(_env)  (((JNIEnvExt*)_env)->baseFuncTable)
185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BASE_VM(_vm)    (((JavaVMExt*)_vm)->baseFuncTable)
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1870423f0e813a3807168fe5524405eb96675532097Andy McFadden#define kRedundantDirectBufferTest false
1888e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Flags passed into checkThread().
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_Default       0x0000
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritBad       0x0000      /* calling while in critical is bad */
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritOkay      0x0001      /* ...okay */
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritGet       0x0002      /* this is a critical "get" */
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritRelease   0x0003      /* this is a critical "release" */
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritMask      0x0003      /* bit mask to get "crit" value */
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_ExcepBad      0x0000      /* raised exceptions are bad */
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_ExcepOkay     0x0004      /* ...okay */
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enter/exit macros for JNI env "check" functions.  These do not change
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the thread state within the VM.
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_ENTER(_env, _flags)                                           \
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        JNI_TRACE(true, true);                                              \
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkThread(_env, _flags, __FUNCTION__);                            \
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_EXIT(_env)                                                    \
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do { JNI_TRACE(false, true); } while(false)
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enter/exit macros for JNI invocation interface "check" functions.  These
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do not change the thread state within the VM.
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set "_hasmeth" to true if we have a valid thread with a method pointer.
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We won't have one before attaching a thread, after detaching a thread, or
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * after destroying the VM.
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_VMENTER(_vm, _hasmeth)                                        \
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do { JNI_TRACE(true, _hasmeth); } while(false)
227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_VMEXIT(_vm, _hasmeth)                                         \
228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do { JNI_TRACE(false, _hasmeth); } while(false)
229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
230ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden#define CHECK_FIELD_TYPE(_env, _obj, _fieldid, _prim, _isstatic)            \
231ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    checkFieldType(_env, _obj, _fieldid, _prim, _isstatic, __FUNCTION__)
2321cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden#define CHECK_INST_FIELD_ID(_env, _obj, _fieldid)                           \
2331cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden    checkInstanceFieldID(_env, _obj, _fieldid, __FUNCTION__)
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_CLASS(_env, _clazz)                                           \
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkClass(_env, _clazz, __FUNCTION__)
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_STRING(_env, _str)                                            \
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkString(_env, _str, __FUNCTION__)
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_UTF_STRING(_env, _str, _nullok)                               \
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkUtfString(_env, _str, _nullok, __FUNCTION__)
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_CLASS_NAME(_env, _str)                                        \
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkClassName(_env, _str, __FUNCTION__)
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_OBJECT(_env, _obj)                                            \
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkObject(_env, _obj, __FUNCTION__)
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_ARRAY(_env, _array)                                           \
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkArray(_env, _array, __FUNCTION__)
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_RELEASE_MODE(_env, _mode)                                     \
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkReleaseMode(_env, _mode, __FUNCTION__)
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_LENGTH_POSITIVE(_env, _length)                                \
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkLengthPositive(_env, _length, __FUNCTION__)
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_NON_NULL(_env, _ptr)                                          \
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkNonNull(_env, _ptr, __FUNCTION__)
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_SIG(_env, _methid, _sigbyte, _isstatic)                       \
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkSig(_env, _methid, _sigbyte, _isstatic, __FUNCTION__)
254a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden#define CHECK_METHOD_ARGS_A(_env, _methid, _args)                           \
255a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    checkMethodArgsA(_env, _methid, _args, __FUNCTION__)
256a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden#define CHECK_METHOD_ARGS_V(_env, _methid, _args)                           \
257a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    checkMethodArgsV(_env, _methid, _args, __FUNCTION__)
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Print trace message when both "checkJNI" and "verbose:jni" are enabled.
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define JNI_TRACE(_entry, _hasmeth)                                         \
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (gDvm.verboseJni && (_entry)) {                                  \
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            static const char* classDescriptor = "???";                     \
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            static const char* methodName = "???";                          \
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (_hasmeth) {                                                 \
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                const Method* meth = dvmGetCurrentJNIMethod();              \
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                classDescriptor = meth->clazz->descriptor;                  \
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                methodName = meth->name;                                    \
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* use +6 to drop the leading "Check_" */                       \
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGI("JNI: %s (from %s.%s)",                                    \
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (__FUNCTION__)+6, classDescriptor, methodName);             \
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Log the current location.
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "func" looks like "Check_DeleteLocalRef"; we drop the "Check_".
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void showLocation(const Method* meth, const char* func)
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("             in %s.%s %s (%s)\n",
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth->clazz->descriptor, meth->name, desc, func + 6);
288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(desc);
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Abort if we are configured to bail out on JNI warnings.
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
29459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFaddenstatic void abortMaybe(void)
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JavaVMExt* vm = (JavaVMExt*) gDvm.vmList;
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (vm->warnError) {
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpThread(dvmThreadSelf(), false);
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the current thread is (a) attached and (b) associated with
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this particular instance of JNIEnv.
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that, if this thread previously made a critical "get" call, we
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do the corresponding "release" call before we try anything else.
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that, if an exception has been raised, the native code doesn't
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * make any JNI calls other than the Exception* methods.
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO? if we add support for non-JNI native calls, make sure that the
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method at the top of the interpreted stack is a JNI method call.  (Or
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set a flag in the Thread/JNIEnv when the call is made and clear it on
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return?)
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: we are still in THREAD_NATIVE mode.  A GC could happen at any time.
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkThread(JNIEnv* env, int flags, const char* func)
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNIEnvExt* threadEnv;
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printException = false;
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* get the *correct* JNIEnv by going through our TLS pointer */
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadEnv = dvmGetJNIEnvForThread();
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Verify that the JNIEnv we've been handed matches what we expected
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to receive.
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (threadEnv == NULL) {
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI ERROR: non-VM thread making JNI calls\n");
335ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        // don't set printWarn -- it'll try to call showLocation()
336ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        dvmAbort();
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if ((JNIEnvExt*) env != threadEnv) {
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmThreadSelf()->threadId != threadEnv->envThreadId) {
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: threadEnv != thread->env?\n");
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmAbort();
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: threadid=%d using env from threadid=%d\n",
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            threadEnv->envThreadId, ((JNIEnvExt*)env)->envThreadId);
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* this is a bad idea -- need to throw as we exit, or abort func */
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //dvmThrowException("Ljava/lang/RuntimeException;",
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //    "invalid use of JNI env ptr");
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (((JNIEnvExt*) env)->self != dvmThreadSelf()) {
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* correct JNIEnv*; make sure the "self" pointer is correct */
352ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        LOGE("JNI ERROR: env->self != thread-self (%p vs. %p)\n",
353ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            ((JNIEnvExt*) env)->self, dvmThreadSelf());
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check for critical resource misuse.
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (flags & kFlag_CritMask) {
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritOkay:    // okay to call this method
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritBad:     // not okay to call
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (threadEnv->critical) {
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: threadid=%d using JNI after critical get\n",
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                threadEnv->envThreadId);
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            printWarn = true;
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritGet:     // this is a "get" call
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* don't check here; we allow nested gets */
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        threadEnv->critical++;
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritRelease: // this is a "release" call
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        threadEnv->critical--;
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (threadEnv->critical < 0) {
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: threadid=%d called too many crit releases\n",
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                threadEnv->envThreadId);
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            printWarn = true;
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check for raised exceptions.
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((flags & kFlag_ExcepOkay) == 0 && dvmCheckException(dvmThreadSelf())) {
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: JNI method called with exception raised\n");
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printException = true;
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printException) {
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Pending exception is:\n");
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmLogExceptionStackTrace();
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the field is of the appropriate type.  If the field has an
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * object type, "obj" is the object we're trying to assign into it.
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Works for both static and instance fields.
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
411ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkFieldType(JNIEnv* env, jobject jobj, jfieldID fieldID,
412ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    PrimitiveType prim, bool isStatic, const char* func)
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const char* primNameList[] = {
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "Object/Array", "boolean", "char", "float", "double",
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "byte", "short", "int", "long", "void"
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    };
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char** primNames = &primNameList[1];      // shift up for PRIM_NOT
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Field* field = (Field*) fieldID;
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (fieldID == NULL) {
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI ERROR: null field ID\n");
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (field->signature[0] == 'L' || field->signature[0] == '[') {
4280423f0e813a3807168fe5524405eb96675532097Andy McFadden        Object* obj = dvmDecodeIndirectRef(env, jobj);
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (obj != NULL) {
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ClassObject* fieldClass =
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmFindLoadedClass(field->signature);
432ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            ClassObject* objClass = obj->clazz;
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(fieldClass != NULL);
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(objClass != NULL);
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!dvmInstanceof(objClass, fieldClass)) {
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGW("JNI WARNING: field '%s' with type '%s' set with wrong type (%s)\n",
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    field->name, field->signature, objClass->descriptor);
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                printWarn = true;
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (field->signature[0] != PRIM_TYPE_TO_LETTER[prim]) {
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: field '%s' with type '%s' set with wrong type (%s)\n",
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            field->name, field->signature, primNames[prim]);
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (isStatic && !dvmIsStaticField(field)) {
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isStatic)
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: accessing non-static field %s as static\n",
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                field->name);
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: accessing static field %s as non-static\n",
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                field->name);
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn) {
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
464ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden * Verify that "jobj" is a valid object, and that it's an object that JNI
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is allowed to know about.  We allow NULL references.
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
467a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * Must be in "running" mode before calling here.
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
469a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenstatic void checkObject0(JNIEnv* env, jobject jobj, const char* func)
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(env);
472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
474ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    if (jobj == NULL)
475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
476702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
477b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden    if (dvmIsWeakGlobalRef(jobj)) {
478b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden        /*
479b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden         * Normalize and continue.  This will tell us if the PhantomReference
480b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden         * object is valid.
481b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden         */
482b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden        jobj = dvmNormalizeWeakGlobalRef((jweak) jobj);
483b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden    }
484b18992f6e3c168742bc7c7d19d662d7719aef5ddAndy McFadden
4850423f0e813a3807168fe5524405eb96675532097Andy McFadden    if (dvmGetJNIRefType(env, jobj) == JNIInvalidRefType) {
486ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        LOGW("JNI WARNING: %p is not a valid JNI reference\n", jobj);
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
4880423f0e813a3807168fe5524405eb96675532097Andy McFadden    } else {
4890423f0e813a3807168fe5524405eb96675532097Andy McFadden        Object* obj = dvmDecodeIndirectRef(env, jobj);
4900423f0e813a3807168fe5524405eb96675532097Andy McFadden
4910423f0e813a3807168fe5524405eb96675532097Andy McFadden        if (obj == NULL || !dvmIsValidObject(obj)) {
4920423f0e813a3807168fe5524405eb96675532097Andy McFadden            LOGW("JNI WARNING: native code passing in bad object %p %p (%s)\n",
4930423f0e813a3807168fe5524405eb96675532097Andy McFadden                jobj, obj, func);
4940423f0e813a3807168fe5524405eb96675532097Andy McFadden            printWarn = true;
4950423f0e813a3807168fe5524405eb96675532097Andy McFadden        }
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn) {
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
502a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden}
503702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
504a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden/*
505a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * Verify that "jobj" is a valid object, and that it's an object that JNI
506a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * is allowed to know about.  We allow NULL references.
507a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden *
508a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * Switches to "running" mode before performing checks.
509a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden */
510a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenstatic void checkObject(JNIEnv* env, jobject jobj, const char* func)
511a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden{
512a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    JNI_ENTER();
513a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    checkObject0(env, jobj, func);
514702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "clazz" actually points to a class object.  (Also performs
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * checkObject.)
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We probably don't need to identify where we're being called from,
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because the VM is most likely about to crash and leave a core dump
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if something is wrong.
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because we're looking at an object on the GC heap, we have to switch
526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to "running" mode before doing the checks.
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkClass(JNIEnv* env, jclass jclazz, const char* func)
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNI_ENTER();
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
533ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz == NULL) {
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: received null jclass\n");
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (!dvmIsValidObject((Object*) clazz)) {
539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: jclass points to invalid object %p\n", clazz);
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (clazz->obj.clazz != gDvm.classJavaLangClass) {
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: jclass does not point to class object (%p - %s)\n",
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            jclazz, clazz->descriptor);
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
546702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
550702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    else
551702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden        checkObject(env, jclazz, func);
552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "str" is non-NULL and points to a String object.
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we're dealing with objects, switch to "running" mode.
558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
559ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkString(JNIEnv* env, jstring jstr, const char* func)
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNI_ENTER();
562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
564ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jstr);
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL) {
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: received null jstring (%s)\n", func);
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (obj->clazz != gDvm.classJavaLangString) {
570ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        /*
571ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * TODO: we probably should test dvmIsValidObject first, because
572ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * this will crash if "obj" is non-null but pointing to an invalid
573ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * memory region.  However, the "is valid" test is a little slow,
574ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * we're doing it again over in checkObject().
575ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         */
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsValidObject(obj))
577ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jstring %p points to non-string object (%s)\n",
578ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden                jstr, func);
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
580ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jstring %p is bogus (%s)\n", jstr, func);
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
583702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
587702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    else
588ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        checkObject(env, jstr, func);
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "bytes" points to valid "modified UTF-8" data.
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkUtfString(JNIEnv* env, const char* bytes, bool nullOk,
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* func)
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* origBytes = bytes;
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (bytes == NULL) {
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!nullOk) {
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: unexpectedly null UTF string\n");
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto fail;
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (*bytes != '\0') {
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u1 utf8 = *(bytes++);
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Switch on the high four bits.
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (utf8 >> 4) {
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x00:
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x01:
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x02:
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x03:
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x04:
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x05:
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x06:
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x07: {
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Bit pattern 0xxx. No need for any extra bytes.
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x08:
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x09:
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0a:
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0b:
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0f: {
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * Bit pattern 10xx or 1111, which are illegal start bytes.
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * Note: 1111 is valid for normal UTF-8, but not the
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * modified UTF-8 used here.
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGW("JNI WARNING: illegal start byte 0x%x\n", utf8);
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                goto fail;
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0e: {
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Bit pattern 1110, so there are two additional bytes.
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                utf8 = *(bytes++);
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if ((utf8 & 0xc0) != 0x80) {
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGW("JNI WARNING: illegal continuation byte 0x%x\n", utf8);
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    goto fail;
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Fall through to take care of the final byte.
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0c:
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0d: {
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Bit pattern 110x, so there is one additional byte.
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                utf8 = *(bytes++);
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if ((utf8 & 0xc0) != 0x80) {
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGW("JNI WARNING: illegal continuation byte 0x%x\n", utf8);
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    goto fail;
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return;
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail:
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("             string: '%s'\n", origBytes);
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    showLocation(dvmGetCurrentJNIMethod(), func);
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    abortMaybe();
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In some circumstances the VM will screen class names, but it doesn't
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for class lookup.  When things get bounced through a class loader, they
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can actually get normalized a couple of times; as a result, passing in
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a class name like "java.lang.Thread" instead of "java/lang/Thread" will
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * work in some circumstances.
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is incorrect and could cause strange behavior or compatibility
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * problems, so we want to screen that out here.
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We expect "full-qualified" class names, like "java/lang/Thread" or
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "[Ljava/lang/Object;".
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkClassName(JNIEnv* env, const char* className, const char* func)
680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* cp;
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* quick check for illegal chars */
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cp = className;
685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (*cp != '\0') {
6864c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden        if (*cp == '.')     /* catch "java.lang.String" */
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto fail;
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cp++;
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
6904c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden    if (*(cp-1) == ';' && *className == 'L')
6914c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden        goto fail;         /* catch "Ljava/lang/String;" */
692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO: need a more rigorous check here
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return;
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail:
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("JNI WARNING: illegal class name '%s' (%s)\n", className, func);
6994c691d1a66c4c721dbc156b5e765edb49c7c67e4Andy McFadden    LOGW("             (should be formed like 'java/lang/String')\n");
700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    abortMaybe();
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "array" is non-NULL and points to an Array object.
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we're dealing with objects, switch to "running" mode.
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
708ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkArray(JNIEnv* env, jarray jarr, const char* func)
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNI_ENTER();
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
713ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jarr);
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL) {
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: received null array (%s)\n", func);
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (obj->clazz->descriptor[0] != '[') {
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsValidObject(obj))
720ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jarray %p points to non-array object (%s)\n",
721ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden                jarr, obj->clazz->descriptor);
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
723ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jarray %p is bogus\n", jarr);
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
727702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
728702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
731702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    else
732ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        checkObject(env, jarr, func);
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the "mode" argument passed to a primitive array Release
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * function is one of the valid values.
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkReleaseMode(JNIEnv* env, jint mode, const char* func)
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: bad value for mode (%d) (%s)\n", mode, func);
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the length argument to array-creation calls is >= 0.
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkLengthPositive(JNIEnv* env, jsize length, const char* func)
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (length < 0) {
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: negative length for array allocation (%s)\n", func);
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the pointer value is non-NULL.
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkNonNull(JNIEnv* env, const void* ptr, const char* func)
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (ptr == NULL) {
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: invalid null pointer (%s)\n", func);
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the method's return type matches the type of call.
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "expectedSigByte" will be 'L' for all objects, including arrays.
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkSig(JNIEnv* env, jmethodID methodID, char expectedSigByte,
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool isStatic, const char* func)
776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* meth = (const Method*) methodID;
778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (expectedSigByte != meth->shorty[0]) {
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: expected return type '%c'\n", expectedSigByte);
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (isStatic && !dvmIsStaticMethod(meth)) {
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isStatic)
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: calling non-static method with static call\n");
786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: calling static method with non-static call\n");
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn) {
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("             calling %s.%s %s\n",
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            meth->clazz->descriptor, meth->name, desc);
795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        free(desc);
796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that this static field ID is valid for this class.
803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
804ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkStaticFieldID(JNIEnv* env, jclass jclazz, jfieldID fieldID)
805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
806ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
807ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    StaticField* base = clazz->sfields;
808ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    int fieldCount = clazz->sfieldCount;
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((StaticField*) fieldID < base ||
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (StaticField*) fieldID >= base + fieldCount)
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: static fieldID %p not valid for class %s\n",
814ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            fieldID, clazz->descriptor);
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("             base=%p count=%d\n", base, fieldCount);
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that this instance field ID is valid for this object.
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
823ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkInstanceFieldID(JNIEnv* env, jobject jobj, jfieldID fieldID,
8241cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden    const char* func)
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
826702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_ENTER();
827702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
828ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    if (jobj == NULL) {
8291cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        LOGW("JNI WARNING: invalid null object (%s)\n", func);
8301cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        abortMaybe();
831702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden        goto bail;
8321cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden    }
8331cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden
834ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jobj);
835ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* clazz = obj->clazz;
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check this class and all of its superclasses for a matching field.
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Don't need to scan interfaces.
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (clazz != NULL) {
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((InstField*) fieldID >= clazz->ifields &&
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (InstField*) fieldID < clazz->ifields + clazz->ifieldCount)
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
845702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden            goto bail;
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        clazz = clazz->super;
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("JNI WARNING: inst fieldID %p not valid for class %s\n",
852ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        fieldID, obj->clazz->descriptor);
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    abortMaybe();
854702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
855702e2486cdabe6df3ec64e752db2958537a11b35Andy McFaddenbail:
856702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
859a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden/*
860a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * Verify that the reference arguments being passed in are appropriate for
861a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * this method.
862a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden *
863a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * At a minimum we want to make sure that the argument is a valid
864a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * reference.  We can also do a class lookup on the method signature
865a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * and verify that the object is an instance of the appropriate class,
866a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * but that's more expensive.
867a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden *
868a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * The basic tests are redundant when indirect references are enabled,
869a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * since reference arguments must always be converted explicitly.  An
870a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * instanceof test would not be redundant, but we're not doing that at
871a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * this time.
872a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden */
873a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenstatic void checkMethodArgsV(JNIEnv* env, jmethodID methodID, va_list args,
874a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    const char* func)
875a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden{
876a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden#ifndef USE_INDIRECT_REF
877a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    JNI_ENTER();
878a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
879a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    const Method* meth = (const Method*) methodID;
880a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    const char* desc = meth->shorty;
881a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    ClassObject* clazz;
882a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
883a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    LOGV("V-checking %s.%s:%s...\n", meth->clazz->descriptor, meth->name, desc);
884a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
885a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    while (*++desc != '\0') {       /* pre-incr to skip return type */
886a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        switch (*desc) {
887a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        case 'L':
888a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            {     /* 'shorty' descr uses L for all refs, incl array */
889a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden                jobject argObj = va_arg(args, jobject);
890a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden                checkObject0(env, argObj, func);
891a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            }
892a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            break;
893a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        case 'D':       /* 8-byte double */
894a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        case 'J':       /* 8-byte long */
895a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        case 'F':       /* floats normalized to doubles */
896a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            (void) va_arg(args, u8);
897a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            break;
898a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        default:        /* Z B C S I -- all passed as 32-bit integers */
899a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            (void) va_arg(args, u4);
900a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            break;
901a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        }
902a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    }
903a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
904a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenbail:
905a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    JNI_EXIT();
906a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden#endif
907a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden}
908a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
909a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden/*
910a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * Same purpose as checkMethodArgsV, but with arguments in an array of
911a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden * jvalue structs.
912a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden */
913a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenstatic void checkMethodArgsA(JNIEnv* env, jmethodID methodID, jvalue* args,
914a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    const char* func)
915a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden{
916a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden#ifndef USE_INDIRECT_REF
917a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    JNI_ENTER();
918a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
919a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    const Method* meth = (const Method*) methodID;
920a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    const char* desc = meth->shorty;
921a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    ClassObject* clazz;
922a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    int idx = 0;
923a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
924a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    LOGV("A-checking %s.%s:%s...\n", meth->clazz->descriptor, meth->name, desc);
925a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
926a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    while (*++desc != '\0') {       /* pre-incr to skip return type */
927a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        if (*desc == 'L') {
928a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            jobject argObj = args[idx].l;
929a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden            checkObject0(env, argObj, func);
930a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        }
931a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
932a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        idx++;
933a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    }
934a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
935a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFaddenbail:
936a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    JNI_EXIT();
937a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden#endif
938a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden}
939a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Guarded arrays
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardLen       512         /* must be multiple of 2 */
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardPattern   0xd5e3      /* uncommon values; d5e3d5e3 invalid addr */
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardMagic     0xffd5aa96
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardExtra     sizeof(GuardExtra)
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* this gets tucked in at the start of the buffer; struct size must be even */
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct GuardExtra {
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4          magic;
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    uLong       adler;
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t      originalLen;
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const void* originalPtr;
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} GuardExtra;
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* find the GuardExtra given the pointer into the "live" data */
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectinline static GuardExtra* getGuardExtra(const void* dataBuf)
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* fullBuf = ((u1*) dataBuf) - kGuardLen / 2;
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (GuardExtra*) fullBuf;
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an oversized buffer to hold the contents of "buf".  Copy it in,
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * filling in the area around it with guard data.
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use a 16-bit pattern to make a rogue memset less likely to elude us.
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* createGuardedCopy(const void* buf, size_t len, bool modOkay)
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GuardExtra* pExtra;
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t newLen = (len + kGuardLen +1) & ~0x01;
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* newBuf;
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2* pat;
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newBuf = (u1*)malloc(newLen);
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (newBuf == NULL) {
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("createGuardedCopy failed on alloc of %d bytes\n", newLen);
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* fill it in with a pattern */
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pat = (u2*) newBuf;
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < (int)newLen / 2; i++)
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pat++ = kGuardPattern;
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* copy the data in; note "len" could be zero */
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memcpy(newBuf + kGuardLen / 2, buf, len);
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* if modification is not expected, grab a checksum */
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    uLong adler = 0;
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!modOkay) {
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        adler = adler32(0L, Z_NULL, 0);
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        adler = adler32(adler, buf, len);
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(uLong*)newBuf = adler;
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra = (GuardExtra*) newBuf;
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->magic = kGuardMagic;
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->adler = adler;
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->originalPtr = buf;
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->originalLen = len;
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newBuf + kGuardLen / 2;
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify the guard area and, if "modOkay" is false, that the data itself
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has not been altered.
101544a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden *
101644a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden * The caller has already checked that "dataBuf" is non-NULL.
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkGuardedCopy(const void* dataBuf, bool modOkay)
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
102044a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    static const u4 kMagicCmp = kGuardMagic;
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* fullBuf = ((const u1*) dataBuf) - kGuardLen / 2;
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
102344a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    size_t len;
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u2* pat;
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
102744a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    /*
102844a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * Before we do anything with "pExtra", check the magic number.  We
102944a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * do the check with memcmp rather than "==" in case the pointer is
103044a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * unaligned.  If it points to completely bogus memory we're going
103144a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * to crash, but there's no easy way around that.
103244a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     */
103344a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
103444a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden        u1 buf[4];
103544a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden        memcpy(buf, &pExtra->magic, 4);
103644a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden        LOGE("JNI: guard magic does not match (found 0x%02x%02x%02x%02x) "
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             "-- incorrect data pointer %p?\n",
103844a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden            buf[3], buf[2], buf[1], buf[0], dataBuf); /* assume little endian */
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
104244a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    len = pExtra->originalLen;
104344a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden
1044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* check bottom half of guard; skip over optional checksum storage */
1045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pat = (u2*) fullBuf;
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = kGuardExtra / 2; i < (int) (kGuardLen / 2 - kGuardExtra) / 2; i++)
1047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
1048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pat[i] != kGuardPattern) {
1049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: guard pattern(1) disturbed at %p + %d\n",
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fullBuf, i*2);
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
1052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int offset = kGuardLen / 2 + len;
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (offset & 0x01) {
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* odd byte; expected value depends on endian-ness of host */
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const u2 patSample = kGuardPattern;
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fullBuf[offset] != ((const u1*) &patSample)[1]) {
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: guard pattern disturbed in odd byte after %p "
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 "(+%d) 0x%02x 0x%02x\n",
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fullBuf, offset, fullBuf[offset], ((const u1*) &patSample)[1]);
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
1064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        offset++;
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* check top half of guard */
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pat = (u2*) (fullBuf + offset);
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < kGuardLen / 4; i++) {
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pat[i] != kGuardPattern) {
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: guard pattern(2) disturbed at %p + %d\n",
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fullBuf, offset + i*2);
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If modification is not expected, verify checksum.  Strictly speaking
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * this is wrong: if we told the client that we made a copy, there's no
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * reason they can't alter the buffer.
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!modOkay) {
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        uLong adler = adler32(0L, Z_NULL, 0);
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        adler = adler32(adler, dataBuf, len);
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pExtra->adler != adler) {
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: buffer modified (0x%08lx vs 0x%08lx) at addr %p\n",
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pExtra->adler, adler, dataBuf);
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up the guard buffer, scrub it, and return the original pointer.
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* freeGuardedCopy(void* dataBuf)
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* fullBuf = ((u1*) dataBuf) - kGuardLen / 2;
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* originalPtr = (void*) pExtra->originalPtr;
1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t len = pExtra->originalLen;
1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1106c19d2a1d798d8626f196d878abcf23a14bee40afElliott Hughes    memset(dataBuf, 0xdd, len);
1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(fullBuf);
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return originalPtr;
1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Just pull out the original pointer.
1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* getGuardedCopyOriginalPtr(const void* dataBuf)
1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (void*) pExtra->originalPtr;
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grab the data length.
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic size_t getGuardedCopyOriginalLen(const void* dataBuf)
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return pExtra->originalLen;
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the width, in bytes, of a primitive type.
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int dvmPrimitiveTypeWidth(PrimitiveType primType)
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const int lengths[PRIM_MAX] = {
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        1,      // boolean
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        2,      // char
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        4,      // float
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        8,      // double
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        1,      // byte
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        2,      // short
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        4,      // int
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        8,      // long
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        -1,     // void
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    };
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(primType >= 0 && primType < PRIM_MAX);
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return lengths[primType];
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a guarded copy of a primitive array.  Modifications to the copied
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data are allowed.  Returns a pointer to the copied data.
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1153ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void* createGuardedPACopy(JNIEnv* env, const jarray jarr,
1154ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    jboolean* isCopy)
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1156ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
1157ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    PrimitiveType primType = arrObj->obj.clazz->elementClass->primitiveType;
1158ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    int len = arrObj->length * dvmPrimitiveTypeWidth(primType);
1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* result;
1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1161ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    result = createGuardedCopy(arrObj->contents, len, true);
1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isCopy != NULL)
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *isCopy = JNI_TRUE;
1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform the array "release" operation, which may or may not copy data
1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * back into the VM, and may or may not release the underlying storage.
1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1173ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void* releaseGuardedPACopy(JNIEnv* env, jarray jarr, void* dataBuf,
1174ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    int mode)
1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1176ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
1177ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    PrimitiveType primType = arrObj->obj.clazz->elementClass->primitiveType;
1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //int len = array->length * dvmPrimitiveTypeWidth(primType);
1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool release, copyBack;
1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* result;
1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!checkGuardedCopy(dataBuf, true)) {
1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI: failed guarded copy check in releaseGuardedPACopy\n");
1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
11851cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        return NULL;
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (mode) {
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 0:
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        release = copyBack = true;
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JNI_ABORT:
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        release = true;
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyBack = false;
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JNI_COMMIT:
1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        release = false;
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyBack = true;
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI: bad release mode %d\n", mode);
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (copyBack) {
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size_t len = getGuardedCopyOriginalLen(dataBuf);
1208ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        memcpy(arrObj->contents, dataBuf, len);
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (release) {
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (u1*) freeGuardedCopy(dataBuf);
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (u1*) getGuardedCopyOriginalPtr(dataBuf);
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* pointer is to the array contents; back up to the array object */
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result -= offsetof(ArrayObject, contents);
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      JNI functions
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_GetVersion(JNIEnv* env)
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetVersion(env);
1235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_DefineClass(JNIEnv* env, const char* name, jobject loader,
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jbyte* buf, jsize bufLen)
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, loader);
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS_NAME(env, name);
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->DefineClass(env, name, loader, buf, bufLen);
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_FindClass(JNIEnv* env, const char* name)
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS_NAME(env, name);
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->FindClass(env, name);
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_GetSuperclass(JNIEnv* env, jclass clazz)
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetSuperclass(env, clazz);
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_IsAssignableFrom(JNIEnv* env, jclass clazz1,
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass clazz2)
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz1);
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz2);
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->IsAssignableFrom(env, clazz1, clazz2);
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jmethodID Check_FromReflectedMethod(JNIEnv* env, jobject method)
1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, method);
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID result;
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->FromReflectedMethod(env, method);
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jfieldID Check_FromReflectedField(JNIEnv* env, jobject field)
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, field);
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jfieldID result;
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->FromReflectedField(env, field);
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_ToReflectedMethod(JNIEnv* env, jclass cls,
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID methodID, jboolean isStatic)
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, cls);
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ToReflectedMethod(env, cls, methodID, isStatic);
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean isStatic)
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, cls);
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ToReflectedField(env, cls, fieldID, isStatic);
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_Throw(JNIEnv* env, jthrowable obj)
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->Throw(env, obj);
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_ThrowNew(JNIEnv* env, jclass clazz, const char* message)
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, message, true);
1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ThrowNew(env, clazz, message);
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jthrowable Check_ExceptionOccurred(JNIEnv* env)
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jthrowable result;
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ExceptionOccurred(env);
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ExceptionDescribe(JNIEnv* env)
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ExceptionDescribe(env);
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ExceptionClear(JNIEnv* env)
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ExceptionClear(env);
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_FatalError(JNIEnv* env, const char* msg)
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, msg, true);
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->FatalError(env, msg);
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_PushLocalFrame(JNIEnv* env, jint capacity)
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->PushLocalFrame(env, capacity);
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_PopLocalFrame(JNIEnv* env, jobject res)
1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, res);
1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->PopLocalFrame(env, res);
1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewGlobalRef(JNIEnv* env, jobject obj)
1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewGlobalRef(env, obj);
1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14080423f0e813a3807168fe5524405eb96675532097Andy McFaddenstatic void Check_DeleteGlobalRef(JNIEnv* env, jobject globalRef)
1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
14110423f0e813a3807168fe5524405eb96675532097Andy McFadden    CHECK_OBJECT(env, globalRef);
14120423f0e813a3807168fe5524405eb96675532097Andy McFadden#ifdef USE_INDIRECT_REF
14130423f0e813a3807168fe5524405eb96675532097Andy McFadden    if (globalRef != NULL &&
14140423f0e813a3807168fe5524405eb96675532097Andy McFadden        dvmGetJNIRefType(env, globalRef) != JNIGlobalRefType)
14150423f0e813a3807168fe5524405eb96675532097Andy McFadden    {
14160423f0e813a3807168fe5524405eb96675532097Andy McFadden        LOGW("JNI WARNING: DeleteGlobalRef on non-global %p (type=%d)\n",
14170423f0e813a3807168fe5524405eb96675532097Andy McFadden            globalRef, dvmGetJNIRefType(env, globalRef));
14180423f0e813a3807168fe5524405eb96675532097Andy McFadden        abortMaybe();
14190423f0e813a3807168fe5524405eb96675532097Andy McFadden    } else
14200423f0e813a3807168fe5524405eb96675532097Andy McFadden#endif
14210423f0e813a3807168fe5524405eb96675532097Andy McFadden    {
14220423f0e813a3807168fe5524405eb96675532097Andy McFadden        BASE_ENV(env)->DeleteGlobalRef(env, globalRef);
14230423f0e813a3807168fe5524405eb96675532097Andy McFadden    }
1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewLocalRef(JNIEnv* env, jobject ref)
1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, ref);
1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewLocalRef(env, ref);
1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
14370423f0e813a3807168fe5524405eb96675532097Andy McFaddenstatic void Check_DeleteLocalRef(JNIEnv* env, jobject localRef)
1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
14400423f0e813a3807168fe5524405eb96675532097Andy McFadden    CHECK_OBJECT(env, localRef);
14410423f0e813a3807168fe5524405eb96675532097Andy McFadden#ifdef USE_INDIRECT_REF
14420423f0e813a3807168fe5524405eb96675532097Andy McFadden    if (localRef != NULL &&
14430423f0e813a3807168fe5524405eb96675532097Andy McFadden        dvmGetJNIRefType(env, localRef) != JNILocalRefType)
14440423f0e813a3807168fe5524405eb96675532097Andy McFadden    {
14450423f0e813a3807168fe5524405eb96675532097Andy McFadden        LOGW("JNI WARNING: DeleteLocalRef on non-local %p (type=%d)\n",
14460423f0e813a3807168fe5524405eb96675532097Andy McFadden            localRef, dvmGetJNIRefType(env, localRef));
14470423f0e813a3807168fe5524405eb96675532097Andy McFadden        abortMaybe();
14480423f0e813a3807168fe5524405eb96675532097Andy McFadden    } else
14490423f0e813a3807168fe5524405eb96675532097Andy McFadden#endif
14500423f0e813a3807168fe5524405eb96675532097Andy McFadden    {
14510423f0e813a3807168fe5524405eb96675532097Andy McFadden        BASE_ENV(env)->DeleteLocalRef(env, localRef);
14520423f0e813a3807168fe5524405eb96675532097Andy McFadden    }
1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_EnsureLocalCapacity(JNIEnv *env, jint capacity)
1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->EnsureLocalCapacity(env, capacity);
1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_IsSameObject(JNIEnv* env, jobject ref1, jobject ref2)
1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, ref1);
1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, ref2);
1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->IsSameObject(env, ref1, ref2);
1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_AllocObject(JNIEnv* env, jclass clazz)
1477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->AllocObject(env, clazz);
1482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewObject(JNIEnv* env, jclass clazz, jmethodID methodID,
1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ...)
1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1492a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    va_list args, tmpArgs;
1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_start(args, methodID);
1495a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
1496a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    va_copy(tmpArgs, args);
1497a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);
1498a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    va_end(tmpArgs);
1499a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectV(env, clazz, methodID, args);
1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_end(args);
1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_list args)
1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1512a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
1513a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    va_list tmpArgs;
1514a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    va_copy(tmpArgs, args);
1515a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);
1516a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    va_end(tmpArgs);
1517a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectV(env, clazz, methodID, args);
1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jvalue* args)
1524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1528a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden
1529a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden    CHECK_METHOD_ARGS_A(env, methodID, args);
1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectA(env, clazz, methodID, args);
1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_GetObjectClass(JNIEnv* env, jobject obj)
1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetObjectClass(env, obj);
1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->IsInstanceOf(env, obj, clazz);
1552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jmethodID Check_GetMethodID(JNIEnv* env, jclass clazz, const char* name,
1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* sig)
1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID result;
1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetMethodID(env, clazz, name, sig);
1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jfieldID Check_GetFieldID(JNIEnv* env, jclass clazz,
1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* name, const char* sig)
1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jfieldID result;
1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetFieldID(env, clazz, name, sig);
1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jmethodID Check_GetStaticMethodID(JNIEnv* env, jclass clazz,
1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* name, const char* sig)
1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID result;
1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStaticMethodID(env, clazz, name, sig);
1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jfieldID Check_GetStaticFieldID(JNIEnv* env, jclass clazz,
1596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* name, const char* sig)
1597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jfieldID result;
1603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStaticFieldID(env, clazz, name, sig);
1604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
160825b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define GET_STATIC_TYPE_FIELD(_ctype, _jname)                               \
1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_GetStatic##_jname##Field(JNIEnv* env, jclass clazz, \
1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID)                                                   \
1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype result;                                                      \
1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkStaticFieldID(env, clazz, fieldID);                            \
1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->GetStatic##_jname##Field(env, clazz,        \
1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fieldID);                                                       \
1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
162125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jobject, Object);
162225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jboolean, Boolean);
162325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jbyte, Byte);
162425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jchar, Char);
162525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jshort, Short);
162625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jint, Int);
162725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jlong, Long);
162825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jfloat, Float);
162925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jdouble, Double);
1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SET_STATIC_TYPE_FIELD(_ctype, _jname, _ftype)                       \
1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_SetStatic##_jname##Field(JNIEnv* env, jclass clazz,   \
1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID, _ctype value)                                     \
1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkStaticFieldID(env, clazz, fieldID);                            \
16380423f0e813a3807168fe5524405eb96675532097Andy McFadden        /* "value" arg only used when type == ref */                        \
1639ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        CHECK_FIELD_TYPE(env, (jobject)(u4)value, fieldID, _ftype, true);   \
1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->SetStatic##_jname##Field(env, clazz, fieldID,        \
1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            value);                                                         \
1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jobject, Object, PRIM_NOT);
1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jboolean, Boolean, PRIM_BOOLEAN);
1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jbyte, Byte, PRIM_BYTE);
1647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jchar, Char, PRIM_CHAR);
1648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jshort, Short, PRIM_SHORT);
1649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jint, Int, PRIM_INT);
1650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jlong, Long, PRIM_LONG);
1651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jfloat, Float, PRIM_FLOAT);
1652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jdouble, Double, PRIM_DOUBLE);
1653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
165425b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define GET_TYPE_FIELD(_ctype, _jname)                                      \
1655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Get##_jname##Field(JNIEnv* env, jobject obj,        \
1656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID)                                                   \
1657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype result;                                                      \
16611cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        CHECK_INST_FIELD_ID(env, obj, fieldID);                             \
1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->Get##_jname##Field(env, obj, fieldID);      \
1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
166625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jobject, Object);
166725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jboolean, Boolean);
166825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jbyte, Byte);
166925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jchar, Char);
167025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jshort, Short);
167125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jint, Int);
167225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jlong, Long);
167325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jfloat, Float);
167425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jdouble, Double);
1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SET_TYPE_FIELD(_ctype, _jname, _ftype)                              \
1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Set##_jname##Field(JNIEnv* env, jobject obj,          \
1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID, _ctype value)                                     \
1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
16821cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        CHECK_INST_FIELD_ID(env, obj, fieldID);                             \
16830423f0e813a3807168fe5524405eb96675532097Andy McFadden        /* "value" arg only used when type == ref */                        \
1684ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        CHECK_FIELD_TYPE(env, (jobject)(u4) value, fieldID, _ftype, false); \
1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Set##_jname##Field(env, obj, fieldID, value);        \
1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jobject, Object, PRIM_NOT);
1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jboolean, Boolean, PRIM_BOOLEAN);
1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jbyte, Byte, PRIM_BYTE);
1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jchar, Char, PRIM_CHAR);
1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jshort, Short, PRIM_SHORT);
1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jint, Int, PRIM_INT);
1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jlong, Long, PRIM_LONG);
1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jfloat, Float, PRIM_FLOAT);
1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jdouble, Double, PRIM_DOUBLE);
1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
169825b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define CALL_VIRTUAL(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig)   \
1699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Call##_jname##Method(JNIEnv* env, jobject obj,      \
1700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jmethodID methodID, ...)                                            \
1701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1706a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_list args, tmpArgs;                                              \
1707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_start(args, methodID);                                           \
1708a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_copy(tmpArgs, args);                                             \
1709a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);                        \
1710a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_end(tmpArgs);                                                    \
1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->Call##_jname##MethodV(env, obj, methodID,   \
1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args);                                                          \
1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_end(args);                                                       \
1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Call##_jname##MethodV(JNIEnv* env, jobject obj,     \
1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jmethodID methodID, va_list args)                                   \
1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1724a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_list tmpArgs;                                                    \
1725a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_copy(tmpArgs, args);                                             \
1726a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);                        \
1727a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_end(tmpArgs);                                                    \
1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->Call##_jname##MethodV(env, obj, methodID,   \
1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args);                                                          \
1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Call##_jname##MethodA(JNIEnv* env, jobject obj,     \
1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jmethodID methodID, jvalue* args)                                   \
1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1740a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_A(env, methodID, args);                           \
1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->Call##_jname##MethodA(env, obj, methodID,   \
1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args);                                                          \
1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
174625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jobject, Object, Object* result, result=, result, 'L');
174725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jboolean, Boolean, jboolean result, result=, result, 'Z');
174825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jbyte, Byte, jbyte result, result=, result, 'B');
174925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jchar, Char, jchar result, result=, result, 'C');
175025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jshort, Short, jshort result, result=, result, 'S');
175125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jint, Int, jint result, result=, result, 'I');
175225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jlong, Long, jlong result, result=, result, 'J');
175325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jfloat, Float, jfloat result, result=, result, 'F');
175425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jdouble, Double, jdouble result, result=, result, 'D');
175525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(void, Void, , , , 'V');
175625b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden
175725b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define CALL_NONVIRTUAL(_ctype, _jname, _retdecl, _retasgn, _retok,         \
175825b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden        _retsig)                                                            \
1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallNonvirtual##_jname##Method(JNIEnv* env,         \
1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jobject obj, jclass clazz, jmethodID methodID, ...)                 \
1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1767a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_list args, tmpArgs;                                              \
1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_start(args, methodID);                                           \
1769a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_copy(tmpArgs, args);                                             \
1770a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);                        \
1771a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_end(tmpArgs);                                                    \
1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallNonvirtual##_jname##MethodV(env, obj,   \
1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clazz, methodID, args);                                         \
1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_end(args);                                                       \
1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallNonvirtual##_jname##MethodV(JNIEnv* env,        \
1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jobject obj, jclass clazz, jmethodID methodID, va_list args)        \
1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1786a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_list tmpArgs;                                                    \
1787a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_copy(tmpArgs, args);                                             \
1788a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);                        \
1789a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_end(tmpArgs);                                                    \
1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallNonvirtual##_jname##MethodV(env, obj,   \
1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clazz, methodID, args);                                         \
1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallNonvirtual##_jname##MethodA(JNIEnv* env,        \
1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jobject obj, jclass clazz, jmethodID methodID, jvalue* args)        \
1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1803a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_A(env, methodID, args);                           \
1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallNonvirtual##_jname##MethodA(env, obj,   \
1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clazz, methodID, args);                                         \
1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
180925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jobject, Object, Object* result, result=, result, 'L');
181025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jboolean, Boolean, jboolean result, result=, result, 'Z');
181125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jbyte, Byte, jbyte result, result=, result, 'B');
181225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jchar, Char, jchar result, result=, result, 'C');
181325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jshort, Short, jshort result, result=, result, 'S');
181425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jint, Int, jint result, result=, result, 'I');
181525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jlong, Long, jlong result, result=, result, 'J');
181625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jfloat, Float, jfloat result, result=, result, 'F');
181725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jdouble, Double, jdouble result, result=, result, 'D');
181825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(void, Void, , , , 'V');
181925b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden
182025b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden
182125b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define CALL_STATIC(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig)    \
1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallStatic##_jname##Method(JNIEnv* env,             \
1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jclass clazz, jmethodID methodID, ...)                              \
1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, true);                            \
1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1829a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_list args, tmpArgs;                                              \
1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_start(args, methodID);                                           \
1831a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_copy(tmpArgs, args);                                             \
1832a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);                        \
1833a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_end(tmpArgs);                                                    \
1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallStatic##_jname##MethodV(env, clazz,     \
1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodID, args);                                                \
1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_end(args);                                                       \
1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallStatic##_jname##MethodV(JNIEnv* env,            \
1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jclass clazz, jmethodID methodID, va_list args)                     \
1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, true);                            \
1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1847a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_list tmpArgs;                                                    \
1848a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_copy(tmpArgs, args);                                             \
1849a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_V(env, methodID, tmpArgs);                        \
1850a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        va_end(tmpArgs);                                                    \
1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallStatic##_jname##MethodV(env, clazz,     \
1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodID, args);                                                \
1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallStatic##_jname##MethodA(JNIEnv* env,            \
1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jclass clazz, jmethodID methodID, jvalue* args)                     \
1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, true);                            \
1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1863a7a9a1478c6e426c1c6e74d56e16a980426b7834Andy McFadden        CHECK_METHOD_ARGS_A(env, methodID, args);                           \
1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallStatic##_jname##MethodA(env, clazz,     \
1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodID, args);                                                \
1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
186925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jobject, Object, Object* result, result=, result, 'L');
187025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jboolean, Boolean, jboolean result, result=, result, 'Z');
187125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jbyte, Byte, jbyte result, result=, result, 'B');
187225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jchar, Char, jchar result, result=, result, 'C');
187325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jshort, Short, jshort result, result=, result, 'S');
187425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jint, Int, jint result, result=, result, 'I');
187525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jlong, Long, jlong result, result=, result, 'J');
187625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jfloat, Float, jfloat result, result=, result, 'F');
187725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jdouble, Double, jdouble result, result=, result, 'D');
187825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(void, Void, , , , 'V');
1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jstring Check_NewString(JNIEnv* env, const jchar* unicodeChars,
1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize len)
1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jstring result;
1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewString(env, unicodeChars, len);
1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jsize Check_GetStringLength(JNIEnv* env, jstring string)
1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize result;
1895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringLength(env, string);
1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const jchar* Check_GetStringChars(JNIEnv* env, jstring string,
1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* result;
1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringChars(env, string, isCopy);
1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
1908d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden        // TODO: fix for indirect
1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = dvmStringLen(string) * 2;
1910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (const jchar*) createGuardedCopy(result, len, false);
1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isCopy != NULL)
1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *isCopy = JNI_TRUE;
1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleaseStringChars(JNIEnv* env, jstring string,
1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* chars)
1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, chars);
1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkGuardedCopy(chars, false)) {
1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: failed guarded copy check in ReleaseStringChars\n");
1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            abortMaybe();
19281cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden            return;
1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        chars = (const jchar*) freeGuardedCopy((jchar*)chars);
1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleaseStringChars(env, string, chars);
1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jstring Check_NewStringUTF(JNIEnv* env, const char* bytes)
1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, bytes, true);
1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jstring result;
1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewStringUTF(env, bytes);
1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jsize Check_GetStringUTFLength(JNIEnv* env, jstring string)
1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize result;
1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringUTFLength(env, string);
1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* Check_GetStringUTFChars(JNIEnv* env, jstring string,
1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* result;
1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringUTFChars(env, string, isCopy);
1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
1964d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden        // TODO: fix for indirect
1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = dvmStringUtf8ByteLen(string) + 1;
1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (const char*) createGuardedCopy(result, len, false);
1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isCopy != NULL)
1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *isCopy = JNI_TRUE;
1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleaseStringUTFChars(JNIEnv* env, jstring string,
1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* utf)
1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, utf);
1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //int len = dvmStringUtf8ByteLen(string) + 1;
1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkGuardedCopy(utf, false)) {
1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: failed guarded copy check in ReleaseStringUTFChars\n");
1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            abortMaybe();
19851cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden            return;
1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        utf = (const char*) freeGuardedCopy((char*)utf);
1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleaseStringUTFChars(env, string, utf);
1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jsize Check_GetArrayLength(JNIEnv* env, jarray array)
1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize result;
1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetArrayLength(env, array);
1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobjectArray Check_NewObjectArray(JNIEnv* env, jsize length,
2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass elementClass, jobject initialElement)
2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, elementClass);
2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, initialElement);
2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_LENGTH_POSITIVE(env, length);
2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobjectArray result;
2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectArray(env, length, elementClass,
2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            initialElement);
2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_GetObjectArrayElement(JNIEnv* env, jobjectArray array,
2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize index)
2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetObjectArrayElement(env, array, index);
2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_SetObjectArrayElement(JNIEnv* env, jobjectArray array,
2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize index, jobject value)
2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->SetObjectArrayElement(env, array, index, value);
2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define NEW_PRIMITIVE_ARRAY(_artype, _jname)                                \
2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _artype Check_New##_jname##Array(JNIEnv* env, jsize length)      \
2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_LENGTH_POSITIVE(env, length);                                 \
2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _artype result;                                                     \
2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->New##_jname##Array(env, length);            \
2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
2045f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean);
2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jbyteArray, Byte);
2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jcharArray, Char);
2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jshortArray, Short);
2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jintArray, Int);
2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jlongArray, Long);
2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jfloatArray, Float);
2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                        \
2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype* Check_Get##_jname##ArrayElements(JNIEnv* env,            \
2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, jboolean* isCopy)                              \
2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype* result;                                                     \
2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->Get##_jname##ArrayElements(env,             \
2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            array, isCopy);                                                 \
2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {           \
2067ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            result = (_ctype*) createGuardedPACopy(env, array, isCopy);     \
2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                    \
2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Release##_jname##ArrayElements(JNIEnv* env,           \
2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, _ctype* elems, jint mode)                      \
2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);                  \
2078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_NON_NULL(env, elems);                                         \
2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_RELEASE_MODE(env, mode);                                      \
2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (((JNIEnvExt*)env)->forceDataCopy) {                             \
2082ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            elems = (_ctype*) releaseGuardedPACopy(env, array, elems, mode);\
2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Release##_jname##ArrayElements(env,                  \
2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            array, elems, mode);                                            \
2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname)                          \
2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Get##_jname##ArrayRegion(JNIEnv* env,                 \
2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, jsize start, jsize len, _ctype* buf)           \
2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Get##_jname##ArrayRegion(env, array, start,          \
2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            len, buf);                                                      \
2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname)                          \
2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Set##_jname##ArrayRegion(JNIEnv* env,                 \
2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, jsize start, jsize len, const _ctype* buf)     \
2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Set##_jname##ArrayRegion(env, array, start,          \
2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            len, buf);                                                      \
2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname, _typechar)                \
2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname);                           \
2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname);                       \
2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);                             \
2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);
2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* TODO: verify primitive array type matches call type */
2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, 'Z');
2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, 'B');
2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, 'C');
2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, 'S');
2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jint, Int, 'I');
2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, 'J');
2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, 'F');
2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_RegisterNatives(JNIEnv* env, jclass clazz,
2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const JNINativeMethod* methods, jint nMethods)
2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
2132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->RegisterNatives(env, clazz, methods, nMethods);
2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_UnregisterNatives(JNIEnv* env, jclass clazz)
2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->UnregisterNatives(env, clazz);
2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_MonitorEnter(JNIEnv* env, jobject obj)
2149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->MonitorEnter(env, obj);
2154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_MonitorExit(JNIEnv* env, jobject obj)
2159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
2161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->MonitorExit(env, obj);
2164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_GetJavaVM(JNIEnv *env, JavaVM **vm)
2169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetJavaVM(env, vm);
2173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_GetStringRegion(JNIEnv* env, jstring str, jsize start,
2178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize len, jchar* buf)
2179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
2181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, str);
2182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->GetStringRegion(env, str, start, len, buf);
2183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
2187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize len, char* buf)
2188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
2190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, str);
2191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->GetStringUTFRegion(env, str, start, len, buf);
2192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* Check_GetPrimitiveArrayCritical(JNIEnv* env, jarray array,
2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritGet);
2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* result;
2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetPrimitiveArrayCritical(env, array, isCopy);
2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
2203ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        result = createGuardedPACopy(env, array, isCopy);
2204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array,
2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* carray, jint mode)
2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritRelease | kFlag_ExcepOkay);
2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, carray);
2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_RELEASE_MODE(env, mode);
2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
2217ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        carray = releaseGuardedPACopy(env, array, carray, mode);
2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const jchar* Check_GetStringCritical(JNIEnv* env, jstring string,
2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritGet);
2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* result;
2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringCritical(env, string, isCopy);
2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
2231d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden        // TODO: fix for indirect
2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = dvmStringLen(string) * 2;
2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (const jchar*) createGuardedCopy(result, len, false);
2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isCopy != NULL)
2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *isCopy = JNI_TRUE;
2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleaseStringCritical(JNIEnv* env, jstring string,
2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* carray)
2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritRelease | kFlag_ExcepOkay);
2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, carray);
2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkGuardedCopy(carray, false)) {
2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: failed guarded copy check in ReleaseStringCritical\n");
2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            abortMaybe();
22511cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden            return;
2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        carray = (const jchar*) freeGuardedCopy((jchar*)carray);
2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleaseStringCritical(env, string, carray);
2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jweak Check_NewWeakGlobalRef(JNIEnv* env, jobject obj)
2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jweak result;
2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewWeakGlobalRef(env, obj);
2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_DeleteWeakGlobalRef(JNIEnv* env, jweak obj)
2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->DeleteWeakGlobalRef(env, obj);
2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_ExceptionCheck(JNIEnv* env)
2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay | kFlag_ExcepOkay);
2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ExceptionCheck(env);
2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobjectRefType Check_GetObjectRefType(JNIEnv* env, jobject obj)
2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobjectRefType result;
2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetObjectRefType(env, obj);
2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewDirectByteBuffer(JNIEnv* env, void* address,
2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jlong capacity)
2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (address == NULL || capacity < 0) {
2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: invalid values for address (%p) or capacity (%ld)\n",
2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            address, (long) capacity);
2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
23051cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        return NULL;
2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewDirectByteBuffer(env, address, capacity);
2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* Check_GetDirectBufferAddress(JNIEnv* env, jobject buf)
2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, buf);
23168e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    void* result = BASE_ENV(env)->GetDirectBufferAddress(env, buf);
2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
23188e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
23198e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    /* optional - check result vs. "safe" implementation */
23208e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    if (kRedundantDirectBufferTest) {
23218e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        jobject platformAddr = NULL;
23228e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        void* checkResult = NULL;
23238e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
23248e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        /*
23258e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * Start by determining if the object supports the DirectBuffer
23268e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * interfaces.  Note this does not guarantee that it's a direct buffer.
23278e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         */
23288e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (JNI_FALSE == (*env)->IsInstanceOf(env, buf,
2329d5ab726b65d7271be261864c7e224fb90bfe06e0Andy McFadden                gDvm.jclassOrgApacheHarmonyNioInternalDirectBuffer))
23308e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        {
23318e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            goto bail;
23328e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
23338e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
23348e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        /*
23358e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * Get the PlatformAddress object.
23368e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         *
23378e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * If this isn't a direct buffer, platformAddr will be NULL and/or an
23388e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * exception will have been thrown.
23398e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         */
23408e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        platformAddr = (*env)->CallObjectMethod(env, buf,
23418e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            (jmethodID) gDvm.methOrgApacheHarmonyNioInternalDirectBuffer_getEffectiveAddress);
23428e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
23438e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if ((*env)->ExceptionCheck(env)) {
23448e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            (*env)->ExceptionClear(env);
23458e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            platformAddr = NULL;
23468e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
23478e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (platformAddr == NULL) {
23488e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            LOGV("Got request for address of non-direct buffer\n");
23498e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            goto bail;
23508e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
23518e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
2352eb9cbc33ee450d9c237a48273595d9f2a05be342Andy McFadden        jclass platformAddrClass = (*env)->FindClass(env,
2353eb9cbc33ee450d9c237a48273595d9f2a05be342Andy McFadden            "org/apache/harmony/luni/platform/PlatformAddress");
2354eb9cbc33ee450d9c237a48273595d9f2a05be342Andy McFadden        jmethodID toLongMethod = (*env)->GetMethodID(env, platformAddrClass,
2355eb9cbc33ee450d9c237a48273595d9f2a05be342Andy McFadden            "toLong", "()J");
23568e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        checkResult = (void*)(u4)(*env)->CallLongMethod(env, platformAddr,
2357eb9cbc33ee450d9c237a48273595d9f2a05be342Andy McFadden                toLongMethod);
23588e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
23598e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    bail:
23608e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (platformAddr != NULL)
23618e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            (*env)->DeleteLocalRef(env, platformAddr);
23628e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
23638e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (result != checkResult) {
23648e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            LOGW("JNI WARNING: direct buffer result mismatch (%p vs %p)\n",
23658e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden                result, checkResult);
23668e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            abortMaybe();
23678e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            /* keep going */
23688e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
23698e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    }
23708e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jlong Check_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, buf);
23788e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    /* TODO: verify "buf" is an instance of java.nio.Buffer */
23798e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    jlong result = BASE_ENV(env)->GetDirectBufferCapacity(env, buf);
2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      JNI invocation functions
2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_DestroyJavaVM(JavaVM* vm)
2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, false);
2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->DestroyJavaVM(vm);
2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, false);
2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env,
2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* thr_args)
2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, false);
2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->AttachCurrentThread(vm, p_env, thr_args);
2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, true);
2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env,
2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* thr_args)
2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, false);
2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args);
2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, true);
2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_DetachCurrentThread(JavaVM* vm)
2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, true);
2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->DetachCurrentThread(vm);
2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, false);
2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_GetEnv(JavaVM* vm, void** env, jint version)
2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, true);
2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->GetEnv(vm, env, version);
2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, true);
2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Function tables
2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const struct JNINativeInterface gCheckNativeInterface = {
2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetVersion,
2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DefineClass,
2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FindClass,
2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FromReflectedMethod,
2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FromReflectedField,
2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ToReflectedMethod,
2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetSuperclass,
2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_IsAssignableFrom,
2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ToReflectedField,
2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_Throw,
2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ThrowNew,
2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionOccurred,
2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionDescribe,
2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionClear,
2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FatalError,
2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_PushLocalFrame,
2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_PopLocalFrame,
2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewGlobalRef,
2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DeleteGlobalRef,
2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DeleteLocalRef,
2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_IsSameObject,
2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewLocalRef,
2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_EnsureLocalCapacity,
2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_AllocObject,
2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObject,
2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObjectV,
2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObjectA,
2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectClass,
2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_IsInstanceOf,
2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetMethodID,
2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallObjectMethod,
2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallObjectMethodV,
2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallObjectMethodA,
2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallBooleanMethod,
2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallBooleanMethodV,
2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallBooleanMethodA,
2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallByteMethod,
2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallByteMethodV,
2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallByteMethodA,
2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallCharMethod,
2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallCharMethodV,
2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallCharMethodA,
2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallShortMethod,
2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallShortMethodV,
2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallShortMethodA,
2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallIntMethod,
2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallIntMethodV,
2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallIntMethodA,
2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallLongMethod,
2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallLongMethodV,
2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallLongMethodA,
2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallFloatMethod,
2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallFloatMethodV,
2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallFloatMethodA,
2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallDoubleMethod,
2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallDoubleMethodV,
2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallDoubleMethodA,
2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallVoidMethod,
2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallVoidMethodV,
2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallVoidMethodA,
2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualObjectMethod,
2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualObjectMethodV,
2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualObjectMethodA,
2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualBooleanMethod,
2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualBooleanMethodV,
2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualBooleanMethodA,
2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualByteMethod,
2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualByteMethodV,
2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualByteMethodA,
2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualCharMethod,
2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualCharMethodV,
2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualCharMethodA,
2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualShortMethod,
2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualShortMethodV,
2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualShortMethodA,
2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualIntMethod,
2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualIntMethodV,
2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualIntMethodA,
2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualLongMethod,
2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualLongMethodV,
2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualLongMethodA,
2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualFloatMethod,
2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualFloatMethodV,
2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualFloatMethodA,
2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualDoubleMethod,
2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualDoubleMethodV,
2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualDoubleMethodA,
2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualVoidMethod,
2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualVoidMethodV,
2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualVoidMethodA,
2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFieldID,
2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectField,
2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetBooleanField,
2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetByteField,
2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetCharField,
2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetShortField,
2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetIntField,
2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetLongField,
2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFloatField,
2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDoubleField,
2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetObjectField,
2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetBooleanField,
2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetByteField,
2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetCharField,
2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetShortField,
2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetIntField,
2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetLongField,
2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetFloatField,
2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetDoubleField,
2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticMethodID,
2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticObjectMethod,
2578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticObjectMethodV,
2579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticObjectMethodA,
2580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticBooleanMethod,
2581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticBooleanMethodV,
2582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticBooleanMethodA,
2583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticByteMethod,
2584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticByteMethodV,
2585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticByteMethodA,
2586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticCharMethod,
2587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticCharMethodV,
2588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticCharMethodA,
2589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticShortMethod,
2590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticShortMethodV,
2591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticShortMethodA,
2592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticIntMethod,
2593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticIntMethodV,
2594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticIntMethodA,
2595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticLongMethod,
2596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticLongMethodV,
2597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticLongMethodA,
2598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticFloatMethod,
2599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticFloatMethodV,
2600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticFloatMethodA,
2601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticDoubleMethod,
2602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticDoubleMethodV,
2603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticDoubleMethodA,
2604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticVoidMethod,
2605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticVoidMethodV,
2606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticVoidMethodA,
2607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticFieldID,
2609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticObjectField,
2611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticBooleanField,
2612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticByteField,
2613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticCharField,
2614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticShortField,
2615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticIntField,
2616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticLongField,
2617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticFloatField,
2618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticDoubleField,
2619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticObjectField,
2621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticBooleanField,
2622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticByteField,
2623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticCharField,
2624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticShortField,
2625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticIntField,
2626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticLongField,
2627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticFloatField,
2628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticDoubleField,
2629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewString,
2631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringLength,
2633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringChars,
2634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseStringChars,
2635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewStringUTF,
2637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringUTFLength,
2638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringUTFChars,
2639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseStringUTFChars,
2640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetArrayLength,
2642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObjectArray,
2643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectArrayElement,
2644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetObjectArrayElement,
2645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewBooleanArray,
2647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewByteArray,
2648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewCharArray,
2649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewShortArray,
2650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewIntArray,
2651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewLongArray,
2652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewFloatArray,
2653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewDoubleArray,
2654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetBooleanArrayElements,
2656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetByteArrayElements,
2657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetCharArrayElements,
2658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetShortArrayElements,
2659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetIntArrayElements,
2660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetLongArrayElements,
2661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFloatArrayElements,
2662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDoubleArrayElements,
2663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseBooleanArrayElements,
2665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseByteArrayElements,
2666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseCharArrayElements,
2667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseShortArrayElements,
2668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseIntArrayElements,
2669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseLongArrayElements,
2670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseFloatArrayElements,
2671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseDoubleArrayElements,
2672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetBooleanArrayRegion,
2674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetByteArrayRegion,
2675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetCharArrayRegion,
2676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetShortArrayRegion,
2677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetIntArrayRegion,
2678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetLongArrayRegion,
2679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFloatArrayRegion,
2680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDoubleArrayRegion,
2681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetBooleanArrayRegion,
2682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetByteArrayRegion,
2683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetCharArrayRegion,
2684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetShortArrayRegion,
2685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetIntArrayRegion,
2686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetLongArrayRegion,
2687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetFloatArrayRegion,
2688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetDoubleArrayRegion,
2689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_RegisterNatives,
2691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_UnregisterNatives,
2692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_MonitorEnter,
2694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_MonitorExit,
2695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetJavaVM,
2697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringRegion,
2699f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringUTFRegion,
2700f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetPrimitiveArrayCritical,
2702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleasePrimitiveArrayCritical,
2703f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2704f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringCritical,
2705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseStringCritical,
2706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewWeakGlobalRef,
2708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DeleteWeakGlobalRef,
2709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionCheck,
2711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewDirectByteBuffer,
2713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDirectBufferAddress,
2714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDirectBufferCapacity,
2715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectRefType
2717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
2718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const struct JNIInvokeInterface gCheckInvokeInterface = {
2719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DestroyJavaVM,
2724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_AttachCurrentThread,
2725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DetachCurrentThread,
2726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetEnv,
2728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_AttachCurrentThreadAsDaemon,
2730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
2731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replace the normal table with the checked table.
2735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmUseCheckedJniEnv(JNIEnvExt* pEnv)
2737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pEnv->funcTable != &gCheckNativeInterface);
2739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pEnv->baseFuncTable = pEnv->funcTable;
2740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pEnv->funcTable = &gCheckNativeInterface;
2741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replace the normal table with the checked table.
2745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmUseCheckedJniVm(JavaVMExt* pVm)
2747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pVm->funcTable != &gCheckInvokeInterface);
2749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pVm->baseFuncTable = pVm->funcTable;
2750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pVm->funcTable = &gCheckInvokeInterface;
2751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2752