CheckJni.c revision 0083d37b0e1c9e542f671cbca2e9db6819ecccba
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.
6059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
6159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFaddenstatic void checkCallCommon(const u4* args, JValue* pResult,
6259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const Method* method, Thread* self)
6359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden{
6459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    assert(pResult->l != NULL);
65ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* resultObj = dvmDecodeIndirectRef(self->jniEnv, pResult->l);
66ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* objClazz = resultObj->clazz;
6759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
6859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    /*
6959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden     * Make sure that pResult->l is an instance of the type this
7059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden     * method was expected to return.
7159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden     */
7259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const char* declType = dexProtoGetReturnType(&method->prototype);
7359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const char* objType = objClazz->descriptor;
7459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    if (strcmp(declType, objType) == 0) {
7559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        /* names match; ignore class loader issues and allow it */
7659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        LOGV("Check %s.%s: %s io %s (FAST-OK)\n",
7759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            method->clazz->descriptor, method->name, objType, declType);
7859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    } else {
7959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        /*
8059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * Names didn't match.  We need to resolve declType in the context
8159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * of method->clazz->classLoader, and compare the class objects
8259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * for equality.
8359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         *
8459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * Since we're returning an instance of declType, it's safe to
8559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * assume that it has been loaded and initialized (or, for the case
8659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * of an array, generated), so we can just look for it in the
8759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         * loaded-classes list.
8859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden         */
8959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        ClassObject* declClazz;
9059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
9159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        declClazz = dvmLookupClass(declType, method->clazz->classLoader, false);
9259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        if (declClazz == NULL) {
9359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("JNI WARNING: method declared to return '%s' returned '%s'\n",
9459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                declType, objType);
9559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("             failed in %s.%s ('%s' not found)\n",
9659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                method->clazz->descriptor, method->name, declType);
9759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            abortMaybe();
9859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            return;
9959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        }
10059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        if (!dvmInstanceof(objClazz, declClazz)) {
10159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("JNI WARNING: method declared to return '%s' returned '%s'\n",
10259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                declType, objType);
10359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGW("             failed in %s.%s\n",
10459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                method->clazz->descriptor, method->name);
10559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            abortMaybe();
10659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            return;
10759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        } else {
10859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden            LOGV("Check %s.%s: %s io %s (SLOW-OK)\n",
10959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden                method->clazz->descriptor, method->name, objType, declType);
11059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        }
11159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    }
11259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden}
11359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
11459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
1150083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * Determine if we need to check the return type coming out of the call.
1160083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden *
1170083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * (We don't do this at the top of checkCallCommon() because this is on
1180083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * the critical path for native method calls.)
1190083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden */
1200083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenstatic inline bool callNeedsCheck(const u4* args, JValue* pResult,
1210083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    const Method* method, Thread* self)
1220083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden{
1230083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    return (method->shorty[0] == 'L' && !dvmCheckException(self) &&
1240083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden            pResult->l != NULL);
1250083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden}
1260083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden
1270083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden/*
12859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * Check a call into native code.
12959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
1300083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_general(const u4* args, JValue* pResult,
13159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const Method* method, Thread* self)
13259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden{
1330083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_general(args, pResult, method, self);
1340083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
13559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        checkCallCommon(args, pResult, method, self);
13659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden}
13759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
13859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
13959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * Check a synchronized call into native code.
14059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
1410083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_synchronized(const u4* args, JValue* pResult,
14259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden    const Method* method, Thread* self)
14359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden{
1440083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_synchronized(args, pResult, method, self);
1450083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
1460083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden        checkCallCommon(args, pResult, method, self);
1470083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden}
1480083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden
1490083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden/*
1500083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * Check a virtual call with no reference arguments (other than "this").
1510083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden */
1520083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_virtualNoRef(const u4* args, JValue* pResult,
1530083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    const Method* method, Thread* self)
1540083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden{
1550083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_virtualNoRef(args, pResult, method, self);
1560083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
1570083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden        checkCallCommon(args, pResult, method, self);
1580083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden}
1590083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden
1600083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden/*
1610083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden * Check a static call with no reference arguments (other than "clazz").
1620083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden */
1630083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFaddenvoid dvmCheckCallJNIMethod_staticNoRef(const u4* args, JValue* pResult,
1640083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    const Method* method, Thread* self)
1650083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden{
1660083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    dvmCallJNIMethod_staticNoRef(args, pResult, method, self);
1670083d37b0e1c9e542f671cbca2e9db6819ecccbaAndy McFadden    if (callNeedsCheck(args, pResult, method, self))
16859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden        checkCallCommon(args, pResult, method, self);
16959b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden}
17059b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
17159b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
17259b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden/*
17359b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * ===========================================================================
17459b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden *      JNI function helpers
17559b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden * ===========================================================================
17659b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden */
17759b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFadden
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define JNI_ENTER()     dvmChangeStatus(NULL, THREAD_RUNNING)
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define JNI_EXIT()      dvmChangeStatus(NULL, THREAD_NATIVE)
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BASE_ENV(_env)  (((JNIEnvExt*)_env)->baseFuncTable)
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define BASE_VM(_vm)    (((JavaVMExt*)_vm)->baseFuncTable)
183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1848e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden#define kRedundantDirectBufferTest true
1858e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Flags passed into checkThread().
188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_Default       0x0000
190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritBad       0x0000      /* calling while in critical is bad */
192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritOkay      0x0001      /* ...okay */
193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritGet       0x0002      /* this is a critical "get" */
194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritRelease   0x0003      /* this is a critical "release" */
195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_CritMask      0x0003      /* bit mask to get "crit" value */
196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_ExcepBad      0x0000      /* raised exceptions are bad */
198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kFlag_ExcepOkay     0x0004      /* ...okay */
199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enter/exit macros for JNI env "check" functions.  These do not change
202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * the thread state within the VM.
203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_ENTER(_env, _flags)                                           \
205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        JNI_TRACE(true, true);                                              \
207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkThread(_env, _flags, __FUNCTION__);                            \
208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_EXIT(_env)                                                    \
211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do { JNI_TRACE(false, true); } while(false)
212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Enter/exit macros for JNI invocation interface "check" functions.  These
216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do not change the thread state within the VM.
217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Set "_hasmeth" to true if we have a valid thread with a method pointer.
219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We won't have one before attaching a thread, after detaching a thread, or
220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * after destroying the VM.
221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_VMENTER(_vm, _hasmeth)                                        \
223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do { JNI_TRACE(true, _hasmeth); } while(false)
224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_VMEXIT(_vm, _hasmeth)                                         \
225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do { JNI_TRACE(false, _hasmeth); } while(false)
226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
227ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden#define CHECK_FIELD_TYPE(_env, _obj, _fieldid, _prim, _isstatic)            \
228ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    checkFieldType(_env, _obj, _fieldid, _prim, _isstatic, __FUNCTION__)
2291cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden#define CHECK_INST_FIELD_ID(_env, _obj, _fieldid)                           \
2301cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden    checkInstanceFieldID(_env, _obj, _fieldid, __FUNCTION__)
231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_CLASS(_env, _clazz)                                           \
232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkClass(_env, _clazz, __FUNCTION__)
233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_STRING(_env, _str)                                            \
234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkString(_env, _str, __FUNCTION__)
235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_UTF_STRING(_env, _str, _nullok)                               \
236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkUtfString(_env, _str, _nullok, __FUNCTION__)
237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_CLASS_NAME(_env, _str)                                        \
238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkClassName(_env, _str, __FUNCTION__)
239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_OBJECT(_env, _obj)                                            \
240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkObject(_env, _obj, __FUNCTION__)
241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_ARRAY(_env, _array)                                           \
242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkArray(_env, _array, __FUNCTION__)
243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_RELEASE_MODE(_env, _mode)                                     \
244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkReleaseMode(_env, _mode, __FUNCTION__)
245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_LENGTH_POSITIVE(_env, _length)                                \
246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkLengthPositive(_env, _length, __FUNCTION__)
247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_NON_NULL(_env, _ptr)                                          \
248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkNonNull(_env, _ptr, __FUNCTION__)
249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define CHECK_SIG(_env, _methid, _sigbyte, _isstatic)                       \
251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    checkSig(_env, _methid, _sigbyte, _isstatic, __FUNCTION__)
252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Print trace message when both "checkJNI" and "verbose:jni" are enabled.
255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define JNI_TRACE(_entry, _hasmeth)                                         \
257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    do {                                                                    \
258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (gDvm.verboseJni && (_entry)) {                                  \
259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            static const char* classDescriptor = "???";                     \
260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            static const char* methodName = "???";                          \
261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (_hasmeth) {                                                 \
262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                const Method* meth = dvmGetCurrentJNIMethod();              \
263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                classDescriptor = meth->clazz->descriptor;                  \
264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                methodName = meth->name;                                    \
265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }                                                               \
266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            /* use +6 to drop the leading "Check_" */                       \
267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGI("JNI: %s (from %s.%s)",                                    \
268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                (__FUNCTION__)+6, classDescriptor, methodName);             \
269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } while(false)
271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Log the current location.
274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "func" looks like "Check_DeleteLocalRef"; we drop the "Check_".
276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void showLocation(const Method* meth, const char* func)
278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("             in %s.%s %s (%s)\n",
281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        meth->clazz->descriptor, meth->name, desc, func + 6);
282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(desc);
283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Abort if we are configured to bail out on JNI warnings.
287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
28859b6177e2fa9c9f1f16d7eff57e481f5282afbdaAndy McFaddenstatic void abortMaybe(void)
289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JavaVMExt* vm = (JavaVMExt*) gDvm.vmList;
291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (vm->warnError) {
292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmDumpThread(dvmThreadSelf(), false);
293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the current thread is (a) attached and (b) associated with
299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * this particular instance of JNIEnv.
300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that, if this thread previously made a critical "get" call, we
302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * do the corresponding "release" call before we try anything else.
303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that, if an exception has been raised, the native code doesn't
305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * make any JNI calls other than the Exception* methods.
306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * TODO? if we add support for non-JNI native calls, make sure that the
308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * method at the top of the interpreted stack is a JNI method call.  (Or
309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * set a flag in the Thread/JNIEnv when the call is made and clear it on
310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * return?)
311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * NOTE: we are still in THREAD_NATIVE mode.  A GC could happen at any time.
313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkThread(JNIEnv* env, int flags, const char* func)
315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNIEnvExt* threadEnv;
317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printException = false;
319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* get the *correct* JNIEnv by going through our TLS pointer */
321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    threadEnv = dvmGetJNIEnvForThread();
322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Verify that the JNIEnv we've been handed matches what we expected
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * to receive.
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (threadEnv == NULL) {
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI ERROR: non-VM thread making JNI calls\n");
329ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        // don't set printWarn -- it'll try to call showLocation()
330ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        dvmAbort();
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if ((JNIEnvExt*) env != threadEnv) {
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmThreadSelf()->threadId != threadEnv->envThreadId) {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: threadEnv != thread->env?\n");
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            dvmAbort();
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: threadid=%d using env from threadid=%d\n",
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            threadEnv->envThreadId, ((JNIEnvExt*)env)->envThreadId);
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* this is a bad idea -- need to throw as we exit, or abort func */
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //dvmThrowException("Ljava/lang/RuntimeException;",
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //    "invalid use of JNI env ptr");
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (((JNIEnvExt*) env)->self != dvmThreadSelf()) {
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* correct JNIEnv*; make sure the "self" pointer is correct */
346ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        LOGE("JNI ERROR: env->self != thread-self (%p vs. %p)\n",
347ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            ((JNIEnvExt*) env)->self, dvmThreadSelf());
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check for critical resource misuse.
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (flags & kFlag_CritMask) {
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritOkay:    // okay to call this method
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritBad:     // not okay to call
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (threadEnv->critical) {
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: threadid=%d using JNI after critical get\n",
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                threadEnv->envThreadId);
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            printWarn = true;
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritGet:     // this is a "get" call
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* don't check here; we allow nested gets */
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        threadEnv->critical++;
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case kFlag_CritRelease: // this is a "release" call
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        threadEnv->critical--;
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (threadEnv->critical < 0) {
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: threadid=%d called too many crit releases\n",
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                threadEnv->envThreadId);
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            printWarn = true;
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        assert(false);
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check for raised exceptions.
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((flags & kFlag_ExcepOkay) == 0 && dvmCheckException(dvmThreadSelf())) {
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: JNI method called with exception raised\n");
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printException = true;
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printException) {
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("Pending exception is:\n");
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmLogExceptionStackTrace();
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the field is of the appropriate type.  If the field has an
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * object type, "obj" is the object we're trying to assign into it.
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Works for both static and instance fields.
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
405ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkFieldType(JNIEnv* env, jobject jobj, jfieldID fieldID,
406ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    PrimitiveType prim, bool isStatic, const char* func)
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const char* primNameList[] = {
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "Object/Array", "boolean", "char", "float", "double",
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        "byte", "short", "int", "long", "void"
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    };
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char** primNames = &primNameList[1];      // shift up for PRIM_NOT
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Field* field = (Field*) fieldID;
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
416ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jobj);
417ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (fieldID == NULL) {
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI ERROR: null field ID\n");
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (field->signature[0] == 'L' || field->signature[0] == '[') {
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (obj != NULL) {
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ClassObject* fieldClass =
426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                dvmFindLoadedClass(field->signature);
427ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            ClassObject* objClass = obj->clazz;
428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(fieldClass != NULL);
430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            assert(objClass != NULL);
431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!dvmInstanceof(objClass, fieldClass)) {
433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGW("JNI WARNING: field '%s' with type '%s' set with wrong type (%s)\n",
434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    field->name, field->signature, objClass->descriptor);
435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                printWarn = true;
436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (field->signature[0] != PRIM_TYPE_TO_LETTER[prim]) {
439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: field '%s' with type '%s' set with wrong type (%s)\n",
440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            field->name, field->signature, primNames[prim]);
441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (isStatic && !dvmIsStaticField(field)) {
443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isStatic)
444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: accessing non-static field %s as static\n",
445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                field->name);
446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: accessing static field %s as non-static\n",
448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                field->name);
449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn) {
453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
459ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden * Verify that "jobj" is a valid object, and that it's an object that JNI
460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * is allowed to know about.  We allow NULL references.
461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
462702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden * Switches to "running" mode before performing checks.
463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
464ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkObject(JNIEnv* env, jobject jobj, const char* func)
465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    UNUSED_PARAMETER(env);
467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
469ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    if (jobj == NULL)
470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
471702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
472ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jobj);
473ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden
474702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_ENTER();
475ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    if (obj == NULL || !dvmIsValidObject(obj)) {
476ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        LOGW("JNI WARNING: native code passing in bad object %p %p (%s)\n",
477ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            jobj, obj, func);
478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
479ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    } else if (dvmGetJNIRefType(env, obj) == JNIInvalidRefType) {
480ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        LOGW("JNI WARNING: %p is not a valid JNI reference\n", jobj);
481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn) {
485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
488702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
489702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "clazz" actually points to a class object.  (Also performs
494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * checkObject.)
495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We probably don't need to identify where we're being called from,
497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * because the VM is most likely about to crash and leave a core dump
498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * if something is wrong.
499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Because we're looking at an object on the GC heap, we have to switch
501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * to "running" mode before doing the checks.
502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkClass(JNIEnv* env, jclass jclazz, const char* func)
504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNI_ENTER();
506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
508ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (clazz == NULL) {
511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: received null jclass\n");
512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (!dvmIsValidObject((Object*) clazz)) {
514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: jclass points to invalid object %p\n", clazz);
515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (clazz->obj.clazz != gDvm.classJavaLangClass) {
517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: jclass does not point to class object (%p - %s)\n",
518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            jclazz, clazz->descriptor);
519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
521702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
525702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    else
526702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden        checkObject(env, jclazz, func);
527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "str" is non-NULL and points to a String object.
531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we're dealing with objects, switch to "running" mode.
533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
534ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkString(JNIEnv* env, jstring jstr, const char* func)
535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNI_ENTER();
537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
539ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jstr);
540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL) {
542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: received null jstring (%s)\n", func);
543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (obj->clazz != gDvm.classJavaLangString) {
545ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        /*
546ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * TODO: we probably should test dvmIsValidObject first, because
547ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * this will crash if "obj" is non-null but pointing to an invalid
548ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * memory region.  However, the "is valid" test is a little slow,
549ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         * we're doing it again over in checkObject().
550ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden         */
551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsValidObject(obj))
552ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jstring %p points to non-string object (%s)\n",
553ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden                jstr, func);
554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
555ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jstring %p is bogus (%s)\n", jstr, func);
556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
558702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
562702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    else
563ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        checkObject(env, jstr, func);
564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "bytes" points to valid "modified UTF-8" data.
568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkUtfString(JNIEnv* env, const char* bytes, bool nullOk,
570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* func)
571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* origBytes = bytes;
573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (bytes == NULL) {
575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!nullOk) {
576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: unexpectedly null UTF string\n");
577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto fail;
578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return;
581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (*bytes != '\0') {
584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        u1 utf8 = *(bytes++);
585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        // Switch on the high four bits.
586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        switch (utf8 >> 4) {
587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x00:
588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x01:
589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x02:
590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x03:
591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x04:
592f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x05:
593f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x06:
594f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x07: {
595f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Bit pattern 0xxx. No need for any extra bytes.
596f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
597f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
598f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x08:
599f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x09:
600f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0a:
601f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0b:
602f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0f: {
603f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                /*
604f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * Bit pattern 10xx or 1111, which are illegal start bytes.
605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * Note: 1111 is valid for normal UTF-8, but not the
606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 * modified UTF-8 used here.
607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 */
608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                LOGW("JNI WARNING: illegal start byte 0x%x\n", utf8);
609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                goto fail;
610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0e: {
612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Bit pattern 1110, so there are two additional bytes.
613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                utf8 = *(bytes++);
614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if ((utf8 & 0xc0) != 0x80) {
615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGW("JNI WARNING: illegal continuation byte 0x%x\n", utf8);
616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    goto fail;
617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Fall through to take care of the final byte.
619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0c:
621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            case 0x0d: {
622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                // Bit pattern 110x, so there is one additional byte.
623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                utf8 = *(bytes++);
624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                if ((utf8 & 0xc0) != 0x80) {
625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    LOGW("JNI WARNING: illegal continuation byte 0x%x\n", utf8);
626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                    goto fail;
627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                }
628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                break;
629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return;
634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail:
636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("             string: '%s'\n", origBytes);
637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    showLocation(dvmGetCurrentJNIMethod(), func);
638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    abortMaybe();
639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * In some circumstances the VM will screen class names, but it doesn't
643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * for class lookup.  When things get bounced through a class loader, they
644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * can actually get normalized a couple of times; as a result, passing in
645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * a class name like "java.lang.Thread" instead of "java/lang/Thread" will
646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * work in some circumstances.
647f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
648f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * This is incorrect and could cause strange behavior or compatibility
649f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * problems, so we want to screen that out here.
650f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
651f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We expect "full-qualified" class names, like "java/lang/Thread" or
652f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "[Ljava/lang/Object;".
653f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
654f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkClassName(JNIEnv* env, const char* className, const char* func)
655f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
656f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* cp;
657f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
658f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* quick check for illegal chars */
659f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    cp = className;
660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (*cp != '\0') {
661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (*cp == '.')
662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            goto fail;
663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        cp++;
664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    // TODO: need a more rigorous check here
667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return;
669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectfail:
671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("JNI WARNING: illegal class name '%s' (%s)\n", className, func);
672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    abortMaybe();
673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that "array" is non-NULL and points to an Array object.
677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Since we're dealing with objects, switch to "running" mode.
679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
680ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkArray(JNIEnv* env, jarray jarr, const char* func)
681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    JNI_ENTER();
683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
685ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jarr);
686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (obj == NULL) {
688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: received null array (%s)\n", func);
689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (obj->clazz->descriptor[0] != '[') {
691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (dvmIsValidObject(obj))
692ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jarray %p points to non-array object (%s)\n",
693ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden                jarr, obj->clazz->descriptor);
694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
695ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            LOGW("JNI WARNING: jarray %p is bogus\n", jarr);
696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
699702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
700702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
701f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn)
702f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
703702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    else
704ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        checkObject(env, jarr, func);
705f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
706f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
707f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
708f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the "mode" argument passed to a primitive array Release
709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * function is one of the valid values.
710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkReleaseMode(JNIEnv* env, jint mode, const char* func)
712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: bad value for mode (%d) (%s)\n", mode, func);
715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the length argument to array-creation calls is >= 0.
721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkLengthPositive(JNIEnv* env, jsize length, const char* func)
723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (length < 0) {
725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: negative length for array allocation (%s)\n", func);
726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the pointer value is non-NULL.
732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkNonNull(JNIEnv* env, const void* ptr, const char* func)
734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (ptr == NULL) {
736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: invalid null pointer (%s)\n", func);
737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that the method's return type matches the type of call.
743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * "expectedSigByte" will be 'L' for all objects, including arrays.
745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void checkSig(JNIEnv* env, jmethodID methodID, char expectedSigByte,
747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool isStatic, const char* func)
748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const Method* meth = (const Method*) methodID;
750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool printWarn = false;
751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (expectedSigByte != meth->shorty[0]) {
753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: expected return type '%c'\n", expectedSigByte);
754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else if (isStatic && !dvmIsStaticMethod(meth)) {
756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isStatic)
757f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: calling non-static method with static call\n");
758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        else
759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGW("JNI WARNING: calling static method with non-static call\n");
760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        printWarn = true;
761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (printWarn) {
764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        char* desc = dexProtoCopyMethodDescriptor(&meth->prototype);
765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("             calling %s.%s %s\n",
766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            meth->clazz->descriptor, meth->name, desc);
767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        free(desc);
768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        showLocation(dvmGetCurrentJNIMethod(), func);
769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that this static field ID is valid for this class.
775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
776ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkStaticFieldID(JNIEnv* env, jclass jclazz, jfieldID fieldID)
777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
778ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(env, jclazz);
779ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    StaticField* base = clazz->sfields;
780ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    int fieldCount = clazz->sfieldCount;
781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if ((StaticField*) fieldID < base ||
783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        (StaticField*) fieldID >= base + fieldCount)
784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: static fieldID %p not valid for class %s\n",
786ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            fieldID, clazz->descriptor);
787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("             base=%p count=%d\n", base, fieldCount);
788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify that this instance field ID is valid for this object.
794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
795ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void checkInstanceFieldID(JNIEnv* env, jobject jobj, jfieldID fieldID,
7961cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden    const char* func)
797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
798702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_ENTER();
799702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
800ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    if (jobj == NULL) {
8011cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        LOGW("JNI WARNING: invalid null object (%s)\n", func);
8021cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        abortMaybe();
803702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden        goto bail;
8041cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden    }
8051cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden
806ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    Object* obj = dvmDecodeIndirectRef(env, jobj);
807ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ClassObject* clazz = obj->clazz;
808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Check this class and all of its superclasses for a matching field.
811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Don't need to scan interfaces.
812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
813f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    while (clazz != NULL) {
814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if ((InstField*) fieldID >= clazz->ifields &&
815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            (InstField*) fieldID < clazz->ifields + clazz->ifieldCount)
816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        {
817702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden            goto bail;
818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        clazz = clazz->super;
821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    LOGW("JNI WARNING: inst fieldID %p not valid for class %s\n",
824ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        fieldID, obj->clazz->descriptor);
825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    abortMaybe();
826702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden
827702e2486cdabe6df3ec64e752db2958537a11b35Andy McFaddenbail:
828702e2486cdabe6df3ec64e752db2958537a11b35Andy McFadden    JNI_EXIT();
829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Guarded arrays
835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardLen       512         /* must be multiple of 2 */
839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardPattern   0xd5e3      /* uncommon values; d5e3d5e3 invalid addr */
840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardMagic     0xffd5aa96
841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define kGuardExtra     sizeof(GuardExtra)
842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* this gets tucked in at the start of the buffer; struct size must be even */
844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projecttypedef struct GuardExtra {
845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u4          magic;
846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    uLong       adler;
847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t      originalLen;
848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const void* originalPtr;
849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project} GuardExtra;
850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* find the GuardExtra given the pointer into the "live" data */
852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectinline static GuardExtra* getGuardExtra(const void* dataBuf)
853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* fullBuf = ((u1*) dataBuf) - kGuardLen / 2;
855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (GuardExtra*) fullBuf;
856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create an oversized buffer to hold the contents of "buf".  Copy it in,
860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * filling in the area around it with guard data.
861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * We use a 16-bit pattern to make a rogue memset less likely to elude us.
863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* createGuardedCopy(const void* buf, size_t len, bool modOkay)
865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GuardExtra* pExtra;
867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t newLen = (len + kGuardLen +1) & ~0x01;
868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* newBuf;
869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u2* pat;
870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    newBuf = (u1*)malloc(newLen);
873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (newBuf == NULL) {
874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("createGuardedCopy failed on alloc of %d bytes\n", newLen);
875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* fill it in with a pattern */
879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pat = (u2*) newBuf;
880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < (int)newLen / 2; i++)
881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *pat++ = kGuardPattern;
882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* copy the data in; note "len" could be zero */
884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memcpy(newBuf + kGuardLen / 2, buf, len);
885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* if modification is not expected, grab a checksum */
887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    uLong adler = 0;
888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!modOkay) {
889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        adler = adler32(0L, Z_NULL, 0);
890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        adler = adler32(adler, buf, len);
891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *(uLong*)newBuf = adler;
892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra = (GuardExtra*) newBuf;
895f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->magic = kGuardMagic;
896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->adler = adler;
897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->originalPtr = buf;
898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pExtra->originalLen = len;
899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return newBuf + kGuardLen / 2;
901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Verify the guard area and, if "modOkay" is false, that the data itself
905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * has not been altered.
90644a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden *
90744a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden * The caller has already checked that "dataBuf" is non-NULL.
908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic bool checkGuardedCopy(const void* dataBuf, bool modOkay)
910f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
91144a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    static const u4 kMagicCmp = kGuardMagic;
912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u1* fullBuf = ((const u1*) dataBuf) - kGuardLen / 2;
913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
91444a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    size_t len;
915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const u2* pat;
916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int i;
917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
91844a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    /*
91944a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * Before we do anything with "pExtra", check the magic number.  We
92044a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * do the check with memcmp rather than "==" in case the pointer is
92144a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * unaligned.  If it points to completely bogus memory we're going
92244a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     * to crash, but there's no easy way around that.
92344a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden     */
92444a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
92544a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden        u1 buf[4];
92644a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden        memcpy(buf, &pExtra->magic, 4);
92744a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden        LOGE("JNI: guard magic does not match (found 0x%02x%02x%02x%02x) "
928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project             "-- incorrect data pointer %p?\n",
92944a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden            buf[3], buf[2], buf[1], buf[0], dataBuf); /* assume little endian */
930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return false;
931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93344a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden    len = pExtra->originalLen;
93444a3484d9ba75aa88c0f3187a9c0ef56e892771bAndy McFadden
935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* check bottom half of guard; skip over optional checksum storage */
936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pat = (u2*) fullBuf;
937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = kGuardExtra / 2; i < (int) (kGuardLen / 2 - kGuardExtra) / 2; i++)
938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {
939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pat[i] != kGuardPattern) {
940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: guard pattern(1) disturbed at %p + %d\n",
941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fullBuf, i*2);
942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    int offset = kGuardLen / 2 + len;
947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (offset & 0x01) {
948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* odd byte; expected value depends on endian-ness of host */
949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        const u2 patSample = kGuardPattern;
950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (fullBuf[offset] != ((const u1*) &patSample)[1]) {
951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: guard pattern disturbed in odd byte after %p "
952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                 "(+%d) 0x%02x 0x%02x\n",
953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fullBuf, offset, fullBuf[offset], ((const u1*) &patSample)[1]);
954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        offset++;
957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* check top half of guard */
960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pat = (u2*) (fullBuf + offset);
961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    for (i = 0; i < kGuardLen / 4; i++) {
962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pat[i] != kGuardPattern) {
963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: guard pattern(2) disturbed at %p + %d\n",
964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                fullBuf, offset + i*2);
965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /*
970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * If modification is not expected, verify checksum.  Strictly speaking
971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * this is wrong: if we told the client that we made a copy, there's no
972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * reason they can't alter the buffer.
973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!modOkay) {
975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        uLong adler = adler32(0L, Z_NULL, 0);
976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        adler = adler32(adler, dataBuf, len);
977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (pExtra->adler != adler) {
978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: buffer modified (0x%08lx vs 0x%08lx) at addr %p\n",
979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                pExtra->adler, adler, dataBuf);
980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return false;
981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return true;
985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Free up the guard buffer, scrub it, and return the original pointer.
989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* freeGuardedCopy(void* dataBuf)
991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* fullBuf = ((u1*) dataBuf) - kGuardLen / 2;
993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* originalPtr = (void*) pExtra->originalPtr;
995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    size_t len = pExtra->originalLen;
996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    memset(dataBuf, len, 0xdd);
998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    free(fullBuf);
999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return originalPtr;
1000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Just pull out the original pointer.
1004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* getGuardedCopyOriginalPtr(const void* dataBuf)
1006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
1008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return (void*) pExtra->originalPtr;
1009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Grab the data length.
1013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic size_t getGuardedCopyOriginalLen(const void* dataBuf)
1015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const GuardExtra* pExtra = getGuardExtra(dataBuf);
1017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return pExtra->originalLen;
1018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Return the width, in bytes, of a primitive type.
1022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic int dvmPrimitiveTypeWidth(PrimitiveType primType)
1024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static const int lengths[PRIM_MAX] = {
1026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        1,      // boolean
1027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        2,      // char
1028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        4,      // float
1029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        8,      // double
1030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        1,      // byte
1031f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        2,      // short
1032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        4,      // int
1033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        8,      // long
1034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        -1,     // void
1035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    };
1036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(primType >= 0 && primType < PRIM_MAX);
1037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return lengths[primType];
1038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Create a guarded copy of a primitive array.  Modifications to the copied
1042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * data are allowed.  Returns a pointer to the copied data.
1043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1044ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void* createGuardedPACopy(JNIEnv* env, const jarray jarr,
1045ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    jboolean* isCopy)
1046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1047ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
1048ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    PrimitiveType primType = arrObj->obj.clazz->elementClass->primitiveType;
1049ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    int len = arrObj->length * dvmPrimitiveTypeWidth(primType);
1050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* result;
1051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1052ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    result = createGuardedCopy(arrObj->contents, len, true);
1053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (isCopy != NULL)
1055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        *isCopy = JNI_TRUE;
1056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Perform the array "release" operation, which may or may not copy data
1062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * back into the VM, and may or may not release the underlying storage.
1063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1064ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFaddenstatic void* releaseGuardedPACopy(JNIEnv* env, jarray jarr, void* dataBuf,
1065ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    int mode)
1066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1067ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
1068ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden    PrimitiveType primType = arrObj->obj.clazz->elementClass->primitiveType;
1069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    //int len = array->length * dvmPrimitiveTypeWidth(primType);
1070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    bool release, copyBack;
1071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    u1* result;
1072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (!checkGuardedCopy(dataBuf, true)) {
1074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI: failed guarded copy check in releaseGuardedPACopy\n");
1075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
10761cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        return NULL;
1077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1078f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    switch (mode) {
1080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case 0:
1081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        release = copyBack = true;
1082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JNI_ABORT:
1084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        release = true;
1085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyBack = false;
1086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    case JNI_COMMIT:
1088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        release = false;
1089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        copyBack = true;
1090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        break;
1091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    default:
1092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGE("JNI: bad release mode %d\n", mode);
1093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        dvmAbort();
1094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return NULL;
1095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (copyBack) {
1098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        size_t len = getGuardedCopyOriginalLen(dataBuf);
1099ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        memcpy(arrObj->contents, dataBuf, len);
1100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (release) {
1103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (u1*) freeGuardedCopy(dataBuf);
1104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    } else {
1105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (u1*) getGuardedCopyOriginalPtr(dataBuf);
1106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /* pointer is to the array contents; back up to the array object */
1109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result -= offsetof(ArrayObject, contents);
1110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
1116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      JNI functions
1118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
1119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
1120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_GetVersion(JNIEnv* env)
1122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetVersion(env);
1126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_DefineClass(JNIEnv* env, const char* name, jobject loader,
1131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jbyte* buf, jsize bufLen)
1132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, loader);
1135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS_NAME(env, name);
1137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->DefineClass(env, name, loader, buf, bufLen);
1139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_FindClass(JNIEnv* env, const char* name)
1144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS_NAME(env, name);
1148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->FindClass(env, name);
1150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_GetSuperclass(JNIEnv* env, jclass clazz)
1155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetSuperclass(env, clazz);
1160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_IsAssignableFrom(JNIEnv* env, jclass clazz1,
1165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass clazz2)
1166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz1);
1169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz2);
1170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
1171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->IsAssignableFrom(env, clazz1, clazz2);
1172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jmethodID Check_FromReflectedMethod(JNIEnv* env, jobject method)
1177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, method);
1180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID result;
1181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->FromReflectedMethod(env, method);
1182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1183f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1184f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1185f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1186f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jfieldID Check_FromReflectedField(JNIEnv* env, jobject field)
1187f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1188f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1189f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, field);
1190f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jfieldID result;
1191f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->FromReflectedField(env, field);
1192f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1193f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1194f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1195f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_ToReflectedMethod(JNIEnv* env, jclass cls,
1197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID methodID, jboolean isStatic)
1198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, cls);
1201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ToReflectedMethod(env, cls, methodID, isStatic);
1203f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1204f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1205f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1206f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1207f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_ToReflectedField(JNIEnv* env, jclass cls, jfieldID fieldID,
1208f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean isStatic)
1209f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, cls);
1212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ToReflectedField(env, cls, fieldID, isStatic);
1214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_Throw(JNIEnv* env, jthrowable obj)
1219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->Throw(env, obj);
1224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_ThrowNew(JNIEnv* env, jclass clazz, const char* message)
1229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, message, true);
1233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ThrowNew(env, clazz, message);
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 jthrowable Check_ExceptionOccurred(JNIEnv* env)
1240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jthrowable result;
1243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ExceptionOccurred(env);
1244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ExceptionDescribe(JNIEnv* env)
1249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ExceptionDescribe(env);
1252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ExceptionClear(JNIEnv* env)
1256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ExceptionClear(env);
1259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_FatalError(JNIEnv* env, const char* msg)
1263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, msg, true);
1266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->FatalError(env, msg);
1267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_PushLocalFrame(JNIEnv* env, jint capacity)
1271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->PushLocalFrame(env, capacity);
1275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_PopLocalFrame(JNIEnv* env, jobject res)
1280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, res);
1283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->PopLocalFrame(env, res);
1285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewGlobalRef(JNIEnv* env, jobject obj)
1290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewGlobalRef(env, obj);
1295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_DeleteGlobalRef(JNIEnv* env, jobject localRef)
1300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, localRef);
1303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->DeleteGlobalRef(env, localRef);
1304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewLocalRef(JNIEnv* env, jobject ref)
1308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, ref);
1311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewLocalRef(env, ref);
1313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_DeleteLocalRef(JNIEnv* env, jobject globalRef)
1318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, globalRef);
1321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->DeleteLocalRef(env, globalRef);
1322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_EnsureLocalCapacity(JNIEnv *env, jint capacity)
1326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->EnsureLocalCapacity(env, capacity);
1330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_IsSameObject(JNIEnv* env, jobject ref1, jobject ref2)
1335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, ref1);
1338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, ref2);
1339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
1340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->IsSameObject(env, ref1, ref2);
1341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_AllocObject(JNIEnv* env, jclass clazz)
1346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->AllocObject(env, clazz);
1351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewObject(JNIEnv* env, jclass clazz, jmethodID methodID,
1356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    ...)
1357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_list args;
1362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_start(args, methodID);
1364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectV(env, clazz, methodID, args);
1365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_end(args);
1366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewObjectV(JNIEnv* env, jclass clazz, jmethodID methodID,
1371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    va_list args)
1372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectV(env, clazz, methodID, args);
1377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewObjectA(JNIEnv* env, jclass clazz, jmethodID methodID,
1381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jvalue* args)
1382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectA(env, clazz, methodID, args);
1387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jclass Check_GetObjectClass(JNIEnv* env, jobject obj)
1392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass result;
1396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetObjectClass(env, obj);
1397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_IsInstanceOf(JNIEnv* env, jobject obj, jclass clazz)
1402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
1407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->IsInstanceOf(env, obj, clazz);
1408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jmethodID Check_GetMethodID(JNIEnv* env, jclass clazz, const char* name,
1413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* sig)
1414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID result;
1420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetMethodID(env, clazz, name, sig);
1421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jfieldID Check_GetFieldID(JNIEnv* env, jclass clazz,
1426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* name, const char* sig)
1427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jfieldID result;
1433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetFieldID(env, clazz, name, sig);
1434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jmethodID Check_GetStaticMethodID(JNIEnv* env, jclass clazz,
1439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* name, const char* sig)
1440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jmethodID result;
1446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStaticMethodID(env, clazz, name, sig);
1447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jfieldID Check_GetStaticFieldID(JNIEnv* env, jclass clazz,
1452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* name, const char* sig)
1453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, name, false);
1457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, sig, false);
1458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jfieldID result;
1459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStaticFieldID(env, clazz, name, sig);
1460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
146425b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define GET_STATIC_TYPE_FIELD(_ctype, _jname)                               \
1465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_GetStatic##_jname##Field(JNIEnv* env, jclass clazz, \
1466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID)                                                   \
1467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype result;                                                      \
1471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkStaticFieldID(env, clazz, fieldID);                            \
1472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->GetStatic##_jname##Field(env, clazz,        \
1473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            fieldID);                                                       \
1474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
1476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
147725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jobject, Object);
147825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jboolean, Boolean);
147925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jbyte, Byte);
148025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jchar, Char);
148125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jshort, Short);
148225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jint, Int);
148325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jlong, Long);
148425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jfloat, Float);
148525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_STATIC_TYPE_FIELD(jdouble, Double);
1486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SET_STATIC_TYPE_FIELD(_ctype, _jname, _ftype)                       \
1488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_SetStatic##_jname##Field(JNIEnv* env, jclass clazz,   \
1489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID, _ctype value)                                     \
1490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        checkStaticFieldID(env, clazz, fieldID);                            \
1494ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        CHECK_FIELD_TYPE(env, (jobject)(u4)value, fieldID, _ftype, true);   \
1495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->SetStatic##_jname##Field(env, clazz, fieldID,        \
1496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            value);                                                         \
1497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jobject, Object, PRIM_NOT);
1500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jboolean, Boolean, PRIM_BOOLEAN);
1501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jbyte, Byte, PRIM_BYTE);
1502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jchar, Char, PRIM_CHAR);
1503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jshort, Short, PRIM_SHORT);
1504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jint, Int, PRIM_INT);
1505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jlong, Long, PRIM_LONG);
1506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jfloat, Float, PRIM_FLOAT);
1507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_STATIC_TYPE_FIELD(jdouble, Double, PRIM_DOUBLE);
1508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
150925b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define GET_TYPE_FIELD(_ctype, _jname)                                      \
1510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Get##_jname##Field(JNIEnv* env, jobject obj,        \
1511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID)                                                   \
1512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype result;                                                      \
15161cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        CHECK_INST_FIELD_ID(env, obj, fieldID);                             \
1517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->Get##_jname##Field(env, obj, fieldID);      \
1518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
1520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
152125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jobject, Object);
152225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jboolean, Boolean);
152325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jbyte, Byte);
152425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jchar, Char);
152525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jshort, Short);
152625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jint, Int);
152725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jlong, Long);
152825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jfloat, Float);
152925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenGET_TYPE_FIELD(jdouble, Double);
1530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SET_TYPE_FIELD(_ctype, _jname, _ftype)                              \
1532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Set##_jname##Field(JNIEnv* env, jobject obj,          \
1533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jfieldID fieldID, _ctype value)                                     \
1534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
15371cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        CHECK_INST_FIELD_ID(env, obj, fieldID);                             \
1538ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        CHECK_FIELD_TYPE(env, (jobject)(u4) value, fieldID, _ftype, false); \
1539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Set##_jname##Field(env, obj, fieldID, value);        \
1540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jobject, Object, PRIM_NOT);
1543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jboolean, Boolean, PRIM_BOOLEAN);
1544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jbyte, Byte, PRIM_BYTE);
1545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jchar, Char, PRIM_CHAR);
1546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jshort, Short, PRIM_SHORT);
1547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jint, Int, PRIM_INT);
1548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jlong, Long, PRIM_LONG);
1549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jfloat, Float, PRIM_FLOAT);
1550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectSET_TYPE_FIELD(jdouble, Double, PRIM_DOUBLE);
1551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
155225b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define CALL_VIRTUAL(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig)   \
1553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Call##_jname##Method(JNIEnv* env, jobject obj,      \
1554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jmethodID methodID, ...)                                            \
1555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_list args;                                                       \
1561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_start(args, methodID);                                           \
1562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->Call##_jname##MethodV(env, obj, methodID,   \
1563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args);                                                          \
1564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_end(args);                                                       \
1565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Call##_jname##MethodV(JNIEnv* env, jobject obj,     \
1569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jmethodID methodID, va_list args)                                   \
1570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->Call##_jname##MethodV(env, obj, methodID,   \
1576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args);                                                          \
1577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1578f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1579f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1580f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_Call##_jname##MethodA(JNIEnv* env, jobject obj,     \
1581f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jmethodID methodID, jvalue* args)                                   \
1582f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1583f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1584f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1585f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1586f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1587f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->Call##_jname##MethodA(env, obj, methodID,   \
1588f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            args);                                                          \
1589f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1590f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1591f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
159225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jobject, Object, Object* result, result=, result, 'L');
159325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jboolean, Boolean, jboolean result, result=, result, 'Z');
159425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jbyte, Byte, jbyte result, result=, result, 'B');
159525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jchar, Char, jchar result, result=, result, 'C');
159625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jshort, Short, jshort result, result=, result, 'S');
159725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jint, Int, jint result, result=, result, 'I');
159825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jlong, Long, jlong result, result=, result, 'J');
159925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jfloat, Float, jfloat result, result=, result, 'F');
160025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(jdouble, Double, jdouble result, result=, result, 'D');
160125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_VIRTUAL(void, Void, , , , 'V');
160225b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden
160325b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define CALL_NONVIRTUAL(_ctype, _jname, _retdecl, _retasgn, _retok,         \
160425b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden        _retsig)                                                            \
1605f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallNonvirtual##_jname##Method(JNIEnv* env,         \
1606f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jobject obj, jclass clazz, jmethodID methodID, ...)                 \
1607f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1608f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1609f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1610f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1611f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1612f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1613f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_list args;                                                       \
1614f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_start(args, methodID);                                           \
1615f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallNonvirtual##_jname##MethodV(env, obj,   \
1616f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clazz, methodID, args);                                         \
1617f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_end(args);                                                       \
1618f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1619f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1620f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1621f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallNonvirtual##_jname##MethodV(JNIEnv* env,        \
1622f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jobject obj, jclass clazz, jmethodID methodID, va_list args)        \
1623f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1624f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1625f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1626f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1627f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1628f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1629f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallNonvirtual##_jname##MethodV(env, obj,   \
1630f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clazz, methodID, args);                                         \
1631f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1632f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1633f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1634f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallNonvirtual##_jname##MethodA(JNIEnv* env,        \
1635f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jobject obj, jclass clazz, jmethodID methodID, jvalue* args)        \
1636f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1637f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1638f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1639f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_OBJECT(env, obj);                                             \
1640f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, false);                           \
1641f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1642f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallNonvirtual##_jname##MethodA(env, obj,   \
1643f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            clazz, methodID, args);                                         \
1644f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1645f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1646f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
164725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jobject, Object, Object* result, result=, result, 'L');
164825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jboolean, Boolean, jboolean result, result=, result, 'Z');
164925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jbyte, Byte, jbyte result, result=, result, 'B');
165025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jchar, Char, jchar result, result=, result, 'C');
165125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jshort, Short, jshort result, result=, result, 'S');
165225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jint, Int, jint result, result=, result, 'I');
165325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jlong, Long, jlong result, result=, result, 'J');
165425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jfloat, Float, jfloat result, result=, result, 'F');
165525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(jdouble, Double, jdouble result, result=, result, 'D');
165625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_NONVIRTUAL(void, Void, , , , 'V');
165725b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden
165825b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden
165925b68266e06c0217b4c8871323da4d665795fa8aAndy McFadden#define CALL_STATIC(_ctype, _jname, _retdecl, _retasgn, _retok, _retsig)    \
1660f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallStatic##_jname##Method(JNIEnv* env,             \
1661f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jclass clazz, jmethodID methodID, ...)                              \
1662f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1663f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1664f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1665f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, true);                            \
1666f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1667f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_list args;                                                       \
1668f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_start(args, methodID);                                           \
1669f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallStatic##_jname##MethodV(env, clazz,     \
1670f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodID, args);                                                \
1671f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        va_end(args);                                                       \
1672f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1673f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1674f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1675f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallStatic##_jname##MethodV(JNIEnv* env,            \
1676f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jclass clazz, jmethodID methodID, va_list args)                     \
1677f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1678f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1679f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1680f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, true);                            \
1681f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1682f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallStatic##_jname##MethodV(env, clazz,     \
1683f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodID, args);                                                \
1684f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1685f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1686f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }                                                                       \
1687f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype Check_CallStatic##_jname##MethodA(JNIEnv* env,            \
1688f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        jclass clazz, jmethodID methodID, jvalue* args)                     \
1689f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1690f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1691f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_CLASS(env, clazz);                                            \
1692f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_SIG(env, methodID, _retsig, true);                            \
1693f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retdecl;                                                           \
1694f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _retasgn BASE_ENV(env)->CallStatic##_jname##MethodA(env, clazz,     \
1695f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            methodID, args);                                                \
1696f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1697f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return _retok;                                                      \
1698f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
169925b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jobject, Object, Object* result, result=, result, 'L');
170025b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jboolean, Boolean, jboolean result, result=, result, 'Z');
170125b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jbyte, Byte, jbyte result, result=, result, 'B');
170225b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jchar, Char, jchar result, result=, result, 'C');
170325b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jshort, Short, jshort result, result=, result, 'S');
170425b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jint, Int, jint result, result=, result, 'I');
170525b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jlong, Long, jlong result, result=, result, 'J');
170625b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jfloat, Float, jfloat result, result=, result, 'F');
170725b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(jdouble, Double, jdouble result, result=, result, 'D');
170825b68266e06c0217b4c8871323da4d665795fa8aAndy McFaddenCALL_STATIC(void, Void, , , , 'V');
1709f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1710f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jstring Check_NewString(JNIEnv* env, const jchar* unicodeChars,
1711f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize len)
1712f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1713f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1714f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jstring result;
1715f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewString(env, unicodeChars, len);
1716f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1717f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1718f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1719f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1720f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jsize Check_GetStringLength(JNIEnv* env, jstring string)
1721f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1722f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1723f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1724f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize result;
1725f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringLength(env, string);
1726f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1727f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1728f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1729f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1730f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const jchar* Check_GetStringChars(JNIEnv* env, jstring string,
1731f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
1732f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1733f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1734f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1735f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* result;
1736f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringChars(env, string, isCopy);
1737f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
1738f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = dvmStringLen(string) * 2;
1739f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (const jchar*) createGuardedCopy(result, len, false);
1740f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isCopy != NULL)
1741f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *isCopy = JNI_TRUE;
1742f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1743f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1744f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1745f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1746f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1747f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleaseStringChars(JNIEnv* env, jstring string,
1748f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* chars)
1749f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1750f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1751f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1752f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, chars);
1753f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
1754f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkGuardedCopy(chars, false)) {
1755f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: failed guarded copy check in ReleaseStringChars\n");
1756f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            abortMaybe();
17571cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden            return;
1758f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1759f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        chars = (const jchar*) freeGuardedCopy((jchar*)chars);
1760f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1761f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleaseStringChars(env, string, chars);
1762f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1763f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1764f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1765f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jstring Check_NewStringUTF(JNIEnv* env, const char* bytes)
1766f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1767f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1768f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_UTF_STRING(env, bytes, true);
1769f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jstring result;
1770f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewStringUTF(env, bytes);
1771f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1772f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1773f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1774f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1775f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jsize Check_GetStringUTFLength(JNIEnv* env, jstring string)
1776f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1777f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1778f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1779f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize result;
1780f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringUTFLength(env, string);
1781f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1782f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1783f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1784f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1785f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const char* Check_GetStringUTFChars(JNIEnv* env, jstring string,
1786f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
1787f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1788f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1789f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1790f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* result;
1791f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringUTFChars(env, string, isCopy);
1792f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
1793f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = dvmStringUtf8ByteLen(string) + 1;
1794f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (const char*) createGuardedCopy(result, len, false);
1795f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isCopy != NULL)
1796f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *isCopy = JNI_TRUE;
1797f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1798f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1799f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1800f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1801f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1802f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleaseStringUTFChars(JNIEnv* env, jstring string,
1803f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const char* utf)
1804f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1805f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_ExcepOkay);
1806f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
1807f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, utf);
1808f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
1809f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //int len = dvmStringUtf8ByteLen(string) + 1;
1810f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkGuardedCopy(utf, false)) {
1811f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: failed guarded copy check in ReleaseStringUTFChars\n");
1812f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            abortMaybe();
18131cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden            return;
1814f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
1815f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        utf = (const char*) freeGuardedCopy((char*)utf);
1816f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1817f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleaseStringUTFChars(env, string, utf);
1818f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1819f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1820f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1821f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jsize Check_GetArrayLength(JNIEnv* env, jarray array)
1822f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1823f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
1824f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
1825f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize result;
1826f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetArrayLength(env, array);
1827f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1828f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1829f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1830f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1831f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobjectArray Check_NewObjectArray(JNIEnv* env, jsize length,
1832f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jclass elementClass, jobject initialElement)
1833f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1834f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1835f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, elementClass);
1836f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, initialElement);
1837f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_LENGTH_POSITIVE(env, length);
1838f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobjectArray result;
1839f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewObjectArray(env, length, elementClass,
1840f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                                            initialElement);
1841f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1842f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1843f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1844f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1845f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_GetObjectArrayElement(JNIEnv* env, jobjectArray array,
1846f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize index)
1847f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1848f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1849f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
1850f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
1851f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetObjectArrayElement(env, array, index);
1852f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1853f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1854f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1855f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1856f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_SetObjectArrayElement(JNIEnv* env, jobjectArray array,
1857f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize index, jobject value)
1858f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1859f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1860f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
1861f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->SetObjectArrayElement(env, array, index, value);
1862f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1863f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1864f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1865f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define NEW_PRIMITIVE_ARRAY(_artype, _jname)                                \
1866f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _artype Check_New##_jname##Array(JNIEnv* env, jsize length)      \
1867f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1868f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1869f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_LENGTH_POSITIVE(env, length);                                 \
1870f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _artype result;                                                     \
1871f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->New##_jname##Array(env, length);            \
1872f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1873f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
1874f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1875f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jbooleanArray, Boolean);
1876f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jbyteArray, Byte);
1877f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jcharArray, Char);
1878f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jshortArray, Short);
1879f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jintArray, Int);
1880f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jlongArray, Long);
1881f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jfloatArray, Float);
1882f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectNEW_PRIMITIVE_ARRAY(jdoubleArray, Double);
1883f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1884f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1885f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                        \
1886f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static _ctype* Check_Get##_jname##ArrayElements(JNIEnv* env,            \
1887f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, jboolean* isCopy)                              \
1888f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1889f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1890f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
1891f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype* result;                                                     \
1892f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = BASE_ENV(env)->Get##_jname##ArrayElements(env,             \
1893f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            array, isCopy);                                                 \
1894f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {           \
1895ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            result = (_ctype*) createGuardedPACopy(env, array, isCopy);     \
1896f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
1897f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1898f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        return result;                                                      \
1899f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1900f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1901f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname)                    \
1902f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Release##_jname##ArrayElements(JNIEnv* env,           \
1903f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, _ctype* elems, jint mode)                      \
1904f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1905f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);                  \
1906f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
1907f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_NON_NULL(env, elems);                                         \
1908f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_RELEASE_MODE(env, mode);                                      \
1909f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (((JNIEnvExt*)env)->forceDataCopy) {                             \
1910ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden            elems = (_ctype*) releaseGuardedPACopy(env, array, elems, mode);\
1911f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }                                                                   \
1912f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Release##_jname##ArrayElements(env,                  \
1913f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            array, elems, mode);                                            \
1914f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1915f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1916f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1917f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname)                          \
1918f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Get##_jname##ArrayRegion(JNIEnv* env,                 \
1919f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, jsize start, jsize len, _ctype* buf)           \
1920f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1921f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1922f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
1923f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Get##_jname##ArrayRegion(env, array, start,          \
1924f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            len, buf);                                                      \
1925f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1926f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1927f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1928f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname)                          \
1929f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void Check_Set##_jname##ArrayRegion(JNIEnv* env,                 \
1930f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        _ctype##Array array, jsize start, jsize len, const _ctype* buf)     \
1931f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    {                                                                       \
1932f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ENTER(env, kFlag_Default);                                    \
1933f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_ARRAY(env, array);                                            \
1934f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        BASE_ENV(env)->Set##_jname##ArrayRegion(env, array, start,          \
1935f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            len, buf);                                                      \
1936f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        CHECK_EXIT(env);                                                    \
1937f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
1938f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1939f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project#define PRIMITIVE_ARRAY_FUNCTIONS(_ctype, _jname, _typechar)                \
1940f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname);                           \
1941f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    RELEASE_PRIMITIVE_ARRAY_ELEMENTS(_ctype, _jname);                       \
1942f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    GET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);                             \
1943f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    SET_PRIMITIVE_ARRAY_REGION(_ctype, _jname);
1944f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1945f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/* TODO: verify primitive array type matches call type */
1946f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jboolean, Boolean, 'Z');
1947f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jbyte, Byte, 'B');
1948f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jchar, Char, 'C');
1949f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jshort, Short, 'S');
1950f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jint, Int, 'I');
1951f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jlong, Long, 'J');
1952f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jfloat, Float, 'F');
1953f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source ProjectPRIMITIVE_ARRAY_FUNCTIONS(jdouble, Double, 'D');
1954f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1955f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_RegisterNatives(JNIEnv* env, jclass clazz,
1956f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const JNINativeMethod* methods, jint nMethods)
1957f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1958f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1959f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1960f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1961f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->RegisterNatives(env, clazz, methods, nMethods);
1962f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1963f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1964f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1965f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1966f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_UnregisterNatives(JNIEnv* env, jclass clazz)
1967f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1968f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1969f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_CLASS(env, clazz);
1970f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1971f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->UnregisterNatives(env, clazz);
1972f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1973f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1974f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1975f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1976f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_MonitorEnter(JNIEnv* env, jobject obj)
1977f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1978f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1979f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1980f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1981f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->MonitorEnter(env, obj);
1982f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1983f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1984f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1985f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1986f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_MonitorExit(JNIEnv* env, jobject obj)
1987f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1988f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
1989f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
1990f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
1991f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->MonitorExit(env, obj);
1992f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
1993f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
1994f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
1995f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
1996f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_GetJavaVM(JNIEnv *env, JavaVM **vm)
1997f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
1998f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
1999f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2000f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetJavaVM(env, vm);
2001f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2002f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2003f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2004f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2005f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_GetStringRegion(JNIEnv* env, jstring str, jsize start,
2006f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize len, jchar* buf)
2007f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2008f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
2009f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, str);
2010f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->GetStringRegion(env, str, start, len, buf);
2011f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2012f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2013f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2014f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_GetStringUTFRegion(JNIEnv* env, jstring str, jsize start,
2015f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jsize len, char* buf)
2016f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2017f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay);
2018f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, str);
2019f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->GetStringUTFRegion(env, str, start, len, buf);
2020f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2021f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2022f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2023f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* Check_GetPrimitiveArrayCritical(JNIEnv* env, jarray array,
2024f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
2025f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2026f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritGet);
2027f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
2028f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* result;
2029f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetPrimitiveArrayCritical(env, array, isCopy);
2030f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
2031ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        result = createGuardedPACopy(env, array, isCopy);
2032f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2033f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2034f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2035f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2036f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2037f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleasePrimitiveArrayCritical(JNIEnv* env, jarray array,
2038f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* carray, jint mode)
2039f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2040f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritRelease | kFlag_ExcepOkay);
2041f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ARRAY(env, array);
2042f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, carray);
2043f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_RELEASE_MODE(env, mode);
2044f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
2045ab00d455ea67fbf4090567bb09ead8017896ea61Andy McFadden        carray = releaseGuardedPACopy(env, array, carray, mode);
2046f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2047f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleasePrimitiveArrayCritical(env, array, carray, mode);
2048f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2049f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2050f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2051f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const jchar* Check_GetStringCritical(JNIEnv* env, jstring string,
2052f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean* isCopy)
2053f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2054f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritGet);
2055f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
2056f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* result;
2057f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetStringCritical(env, string, isCopy);
2058f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy && result != NULL) {
2059f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        int len = dvmStringLen(string) * 2;
2060f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        result = (const jchar*) createGuardedCopy(result, len, false);
2061f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (isCopy != NULL)
2062f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            *isCopy = JNI_TRUE;
2063f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2064f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2065f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2066f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2067f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2068f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_ReleaseStringCritical(JNIEnv* env, jstring string,
2069f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    const jchar* carray)
2070f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2071f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritRelease | kFlag_ExcepOkay);
2072f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_STRING(env, string);
2073f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_NON_NULL(env, carray);
2074f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (((JNIEnvExt*)env)->forceDataCopy) {
2075f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        if (!checkGuardedCopy(carray, false)) {
2076f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            LOGE("JNI: failed guarded copy check in ReleaseStringCritical\n");
2077f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            abortMaybe();
20781cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden            return;
2079f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
2080f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        carray = (const jchar*) freeGuardedCopy((jchar*)carray);
2081f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2082f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->ReleaseStringCritical(env, string, carray);
2083f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2084f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2085f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2086f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jweak Check_NewWeakGlobalRef(JNIEnv* env, jobject obj)
2087f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2088f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2089f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2090f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jweak result;
2091f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewWeakGlobalRef(env, obj);
2092f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2093f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2094f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2095f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2096f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void Check_DeleteWeakGlobalRef(JNIEnv* env, jweak obj)
2097f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2098f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default | kFlag_ExcepOkay);
2099f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    BASE_ENV(env)->DeleteWeakGlobalRef(env, obj);
2101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jboolean Check_ExceptionCheck(JNIEnv* env)
2105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_CritOkay | kFlag_ExcepOkay);
2107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jboolean result;
2108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->ExceptionCheck(env);
2109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobjectRefType Check_GetObjectRefType(JNIEnv* env, jobject obj)
2114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, obj);
2117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobjectRefType result;
2118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->GetObjectRefType(env, obj);
2119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jobject Check_NewDirectByteBuffer(JNIEnv* env, void* address,
2124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jlong capacity)
2125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jobject result;
2128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    if (address == NULL || capacity < 0) {
2129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        LOGW("JNI WARNING: invalid values for address (%p) or capacity (%ld)\n",
2130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            address, (long) capacity);
2131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        abortMaybe();
21321cf3b27e857824af08bab76489b6e25a213edc8dAndy McFadden        return NULL;
2133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
2134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_ENV(env)->NewDirectByteBuffer(env, address, capacity);
2135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
2136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic void* Check_GetDirectBufferAddress(JNIEnv* env, jobject buf)
2140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, buf);
21438e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    void* result = BASE_ENV(env)->GetDirectBufferAddress(env, buf);
2144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_EXIT(env);
21458e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21468e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    /* optional - check result vs. "safe" implementation */
21478e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    if (kRedundantDirectBufferTest) {
21488e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        jobject platformAddr = NULL;
21498e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        void* checkResult = NULL;
21508e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21518e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        /*
21528e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * Start by determining if the object supports the DirectBuffer
21538e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * interfaces.  Note this does not guarantee that it's a direct buffer.
21548e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         */
21558e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (JNI_FALSE == (*env)->IsInstanceOf(env, buf,
21568e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden                (jclass) gDvm.classOrgApacheHarmonyNioInternalDirectBuffer))
21578e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        {
21588e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            goto bail;
21598e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
21608e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21618e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        /*
21628e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * Get the PlatformAddress object.
21638e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         *
21648e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * If this isn't a direct buffer, platformAddr will be NULL and/or an
21658e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         * exception will have been thrown.
21668e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden         */
21678e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        platformAddr = (*env)->CallObjectMethod(env, buf,
21688e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            (jmethodID) gDvm.methOrgApacheHarmonyNioInternalDirectBuffer_getEffectiveAddress);
21698e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21708e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if ((*env)->ExceptionCheck(env)) {
21718e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            (*env)->ExceptionClear(env);
21728e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            platformAddr = NULL;
21738e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
21748e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (platformAddr == NULL) {
21758e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            LOGV("Got request for address of non-direct buffer\n");
21768e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            goto bail;
21778e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
21788e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21798e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        Method* toLong = ((Object*)platformAddr)->clazz->vtable[
21808e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden                gDvm.voffOrgApacheHarmonyLuniPlatformPlatformAddress_toLong];
21818e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        checkResult = (void*)(u4)(*env)->CallLongMethod(env, platformAddr,
21828e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden                (jmethodID)toLong);
21838e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21848e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    bail:
21858e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (platformAddr != NULL)
21868e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            (*env)->DeleteLocalRef(env, platformAddr);
21878e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
21888e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        if (result != checkResult) {
21898e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            LOGW("JNI WARNING: direct buffer result mismatch (%p vs %p)\n",
21908e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden                result, checkResult);
21918e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            abortMaybe();
21928e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden            /* keep going */
21938e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden        }
21948e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    }
21958e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden
2196f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2197f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2198f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2199f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jlong Check_GetDirectBufferCapacity(JNIEnv* env, jobject buf)
2200f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2201f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_ENTER(env, kFlag_Default);
2202f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_OBJECT(env, buf);
22038e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    /* TODO: verify "buf" is an instance of java.nio.Buffer */
22048e5c78470229fd2f5474574081eaa4a2286aafeaAndy McFadden    jlong result = BASE_ENV(env)->GetDirectBufferCapacity(env, buf);
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 Project
2210f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2211f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2212f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      JNI invocation functions
2213f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2214f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2215f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2216f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_DestroyJavaVM(JavaVM* vm)
2217f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2218f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, false);
2219f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2220f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->DestroyJavaVM(vm);
2221f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, false);
2222f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2223f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2224f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2225f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env,
2226f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* thr_args)
2227f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2228f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, false);
2229f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2230f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->AttachCurrentThread(vm, p_env, thr_args);
2231f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, true);
2232f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2233f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2234f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2235f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env,
2236f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    void* thr_args)
2237f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2238f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, false);
2239f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2240f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args);
2241f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, true);
2242f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2243f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2244f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2245f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_DetachCurrentThread(JavaVM* vm)
2246f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2247f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, true);
2248f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2249f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->DetachCurrentThread(vm);
2250f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, false);
2251f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2252f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2253f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2254f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic jint Check_GetEnv(JavaVM* vm, void** env, jint version)
2255f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2256f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMENTER(vm, true);
2257f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    jint result;
2258f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    result = BASE_VM(vm)->GetEnv(vm, env, version);
2259f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    CHECK_VMEXIT(vm, true);
2260f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    return result;
2261f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2262f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2263f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2264f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2265f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2266f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      Function tables
2267f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * ===========================================================================
2268f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2269f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2270f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const struct JNINativeInterface gCheckNativeInterface = {
2271f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2272f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2273f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2274f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2275f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2276f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetVersion,
2277f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2278f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DefineClass,
2279f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FindClass,
2280f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2281f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FromReflectedMethod,
2282f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FromReflectedField,
2283f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ToReflectedMethod,
2284f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2285f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetSuperclass,
2286f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_IsAssignableFrom,
2287f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2288f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ToReflectedField,
2289f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2290f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_Throw,
2291f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ThrowNew,
2292f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionOccurred,
2293f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionDescribe,
2294f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionClear,
2295f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_FatalError,
2296f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2297f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_PushLocalFrame,
2298f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_PopLocalFrame,
2299f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2300f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewGlobalRef,
2301f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DeleteGlobalRef,
2302f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DeleteLocalRef,
2303f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_IsSameObject,
2304f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewLocalRef,
2305f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_EnsureLocalCapacity,
2306f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2307f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_AllocObject,
2308f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObject,
2309f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObjectV,
2310f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObjectA,
2311f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2312f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectClass,
2313f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_IsInstanceOf,
2314f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2315f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetMethodID,
2316f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2317f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallObjectMethod,
2318f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallObjectMethodV,
2319f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallObjectMethodA,
2320f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallBooleanMethod,
2321f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallBooleanMethodV,
2322f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallBooleanMethodA,
2323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallByteMethod,
2324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallByteMethodV,
2325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallByteMethodA,
2326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallCharMethod,
2327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallCharMethodV,
2328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallCharMethodA,
2329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallShortMethod,
2330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallShortMethodV,
2331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallShortMethodA,
2332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallIntMethod,
2333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallIntMethodV,
2334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallIntMethodA,
2335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallLongMethod,
2336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallLongMethodV,
2337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallLongMethodA,
2338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallFloatMethod,
2339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallFloatMethodV,
2340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallFloatMethodA,
2341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallDoubleMethod,
2342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallDoubleMethodV,
2343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallDoubleMethodA,
2344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallVoidMethod,
2345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallVoidMethodV,
2346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallVoidMethodA,
2347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualObjectMethod,
2349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualObjectMethodV,
2350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualObjectMethodA,
2351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualBooleanMethod,
2352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualBooleanMethodV,
2353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualBooleanMethodA,
2354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualByteMethod,
2355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualByteMethodV,
2356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualByteMethodA,
2357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualCharMethod,
2358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualCharMethodV,
2359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualCharMethodA,
2360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualShortMethod,
2361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualShortMethodV,
2362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualShortMethodA,
2363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualIntMethod,
2364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualIntMethodV,
2365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualIntMethodA,
2366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualLongMethod,
2367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualLongMethodV,
2368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualLongMethodA,
2369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualFloatMethod,
2370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualFloatMethodV,
2371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualFloatMethodA,
2372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualDoubleMethod,
2373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualDoubleMethodV,
2374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualDoubleMethodA,
2375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualVoidMethod,
2376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualVoidMethodV,
2377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallNonvirtualVoidMethodA,
2378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFieldID,
2380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectField,
2382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetBooleanField,
2383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetByteField,
2384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetCharField,
2385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetShortField,
2386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetIntField,
2387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetLongField,
2388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFloatField,
2389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDoubleField,
2390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetObjectField,
2391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetBooleanField,
2392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetByteField,
2393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetCharField,
2394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetShortField,
2395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetIntField,
2396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetLongField,
2397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetFloatField,
2398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetDoubleField,
2399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticMethodID,
2401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticObjectMethod,
2403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticObjectMethodV,
2404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticObjectMethodA,
2405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticBooleanMethod,
2406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticBooleanMethodV,
2407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticBooleanMethodA,
2408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticByteMethod,
2409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticByteMethodV,
2410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticByteMethodA,
2411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticCharMethod,
2412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticCharMethodV,
2413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticCharMethodA,
2414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticShortMethod,
2415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticShortMethodV,
2416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticShortMethodA,
2417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticIntMethod,
2418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticIntMethodV,
2419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticIntMethodA,
2420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticLongMethod,
2421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticLongMethodV,
2422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticLongMethodA,
2423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticFloatMethod,
2424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticFloatMethodV,
2425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticFloatMethodA,
2426f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticDoubleMethod,
2427f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticDoubleMethodV,
2428f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticDoubleMethodA,
2429f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticVoidMethod,
2430f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticVoidMethodV,
2431f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_CallStaticVoidMethodA,
2432f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2433f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticFieldID,
2434f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2435f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticObjectField,
2436f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticBooleanField,
2437f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticByteField,
2438f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticCharField,
2439f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticShortField,
2440f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticIntField,
2441f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticLongField,
2442f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticFloatField,
2443f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStaticDoubleField,
2444f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2445f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticObjectField,
2446f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticBooleanField,
2447f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticByteField,
2448f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticCharField,
2449f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticShortField,
2450f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticIntField,
2451f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticLongField,
2452f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticFloatField,
2453f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetStaticDoubleField,
2454f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2455f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewString,
2456f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2457f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringLength,
2458f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringChars,
2459f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseStringChars,
2460f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2461f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewStringUTF,
2462f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringUTFLength,
2463f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringUTFChars,
2464f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseStringUTFChars,
2465f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2466f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetArrayLength,
2467f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewObjectArray,
2468f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectArrayElement,
2469f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetObjectArrayElement,
2470f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2471f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewBooleanArray,
2472f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewByteArray,
2473f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewCharArray,
2474f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewShortArray,
2475f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewIntArray,
2476f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewLongArray,
2477f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewFloatArray,
2478f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewDoubleArray,
2479f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2480f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetBooleanArrayElements,
2481f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetByteArrayElements,
2482f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetCharArrayElements,
2483f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetShortArrayElements,
2484f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetIntArrayElements,
2485f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetLongArrayElements,
2486f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFloatArrayElements,
2487f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDoubleArrayElements,
2488f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2489f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseBooleanArrayElements,
2490f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseByteArrayElements,
2491f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseCharArrayElements,
2492f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseShortArrayElements,
2493f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseIntArrayElements,
2494f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseLongArrayElements,
2495f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseFloatArrayElements,
2496f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseDoubleArrayElements,
2497f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2498f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetBooleanArrayRegion,
2499f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetByteArrayRegion,
2500f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetCharArrayRegion,
2501f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetShortArrayRegion,
2502f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetIntArrayRegion,
2503f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetLongArrayRegion,
2504f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetFloatArrayRegion,
2505f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDoubleArrayRegion,
2506f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetBooleanArrayRegion,
2507f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetByteArrayRegion,
2508f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetCharArrayRegion,
2509f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetShortArrayRegion,
2510f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetIntArrayRegion,
2511f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetLongArrayRegion,
2512f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetFloatArrayRegion,
2513f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_SetDoubleArrayRegion,
2514f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2515f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_RegisterNatives,
2516f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_UnregisterNatives,
2517f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2518f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_MonitorEnter,
2519f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_MonitorExit,
2520f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2521f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetJavaVM,
2522f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2523f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringRegion,
2524f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringUTFRegion,
2525f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2526f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetPrimitiveArrayCritical,
2527f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleasePrimitiveArrayCritical,
2528f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2529f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetStringCritical,
2530f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ReleaseStringCritical,
2531f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2532f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewWeakGlobalRef,
2533f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DeleteWeakGlobalRef,
2534f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2535f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_ExceptionCheck,
2536f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2537f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_NewDirectByteBuffer,
2538f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDirectBufferAddress,
2539f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetDirectBufferCapacity,
2540f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2541f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetObjectRefType
2542f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
2543f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectstatic const struct JNIInvokeInterface gCheckInvokeInterface = {
2544f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2545f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2546f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    NULL,
2547f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2548f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DestroyJavaVM,
2549f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_AttachCurrentThread,
2550f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_DetachCurrentThread,
2551f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2552f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_GetEnv,
2553f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2554f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    Check_AttachCurrentThreadAsDaemon,
2555f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project};
2556f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2557f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2558f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2559f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replace the normal table with the checked table.
2560f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2561f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmUseCheckedJniEnv(JNIEnvExt* pEnv)
2562f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2563f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pEnv->funcTable != &gCheckNativeInterface);
2564f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pEnv->baseFuncTable = pEnv->funcTable;
2565f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pEnv->funcTable = &gCheckNativeInterface;
2566f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2567f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2568f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2569f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Replace the normal table with the checked table.
2570f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
2571f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectvoid dvmUseCheckedJniVm(JavaVMExt* pVm)
2572f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project{
2573f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    assert(pVm->funcTable != &gCheckInvokeInterface);
2574f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pVm->baseFuncTable = pVm->funcTable;
2575f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    pVm->funcTable = &gCheckInvokeInterface;
2576f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
2577f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
2578