summaryrefslogtreecommitdiff
path: root/native/jni
diff options
context:
space:
mode:
authorAndrew John Hughes <gnu_andrew@member.fsf.org>2010-08-10 20:45:13 +0000
committerAndrew John Hughes <gnu_andrew@member.fsf.org>2010-08-10 20:45:13 +0000
commit7da2fbf12a6c1b6ffd24af9ee226ee36caf91162 (patch)
treee0d7d7e604de7b606ee4f9d2f0ec38e3cf39d3a2 /native/jni
parent98daf6c90b72e55a37927590f78be75b09eaf3a8 (diff)
downloadclasspath-7da2fbf12a6c1b6ffd24af9ee226ee36caf91162.tar.gz
jcl changes:
1. Minor fix for JCL_realloc() (don't call free(ptr) if ptr is null like in JCL_free); 2. 32/64-bit code variants collapsed by introducing several macros (which select the proper class name, primitive type, etc.); 3. new recognized macro (JCL_NO_JNIONLOAD) which removes the need for JNI_OnLoad (thus, if JCL_NO_JNIONLOAD is defined, it is possible to link jcl.c statically). 2010-04-12 Ivan Maidanski <ivmai@mail.ru> * native/jni/classpath/jcl.c: Simplify attribute #ifndef block. (JCL_POINTER_CLASSNAME): Define dependent on size of void*. (JCL_POINTER_DATASIGN): Likewise. (JCL_POINTER_INTTYPE): Likewise. (JCL_POINTER_GETFIELD): Likewise. (JNI_OnLoad): Define only if not JCL_NO_JNIONLOAD. Use JCL_POINTER_xxx macros instead of SIZEOF_VOID_P. (JCL_NewRawDataObject): Use JCL_POINTER_xxx macros instead of SIZEOF_VOID_P. Initialize rawDataClass, rawData_fid, rawData_mid global variables if JCL_NO_JNIONLOAD. (JCL_realloc): Don't call free() for NULL pointer. (JCL_GetRawData): Use JCL_POINTER_xxx macros instead of SIZEOF_VOID_P. Initialize rawDataClass, rawData_fid, rawData_mid global variables if JCL_NO_JNIONLOAD.
Diffstat (limited to 'native/jni')
-rw-r--r--native/jni/classpath/jcl.c128
1 files changed, 87 insertions, 41 deletions
diff --git a/native/jni/classpath/jcl.c b/native/jni/classpath/jcl.c
index 0180ab9f0..09709654b 100644
--- a/native/jni/classpath/jcl.c
+++ b/native/jni/classpath/jcl.c
@@ -1,5 +1,5 @@
/* jcl.c
- Copyright (C) 1998, 2005, 2006, 2008 Free Software Foundation, Inc.
+ Copyright (C) 1998, 2005, 2006, 2008, 2010 Free Software Foundation, Inc.
This file is part of GNU Classpath.
@@ -7,7 +7,7 @@ GNU Classpath is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-
+
GNU Classpath is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
@@ -42,12 +42,24 @@ exception statement from your version. */
#include <stdio.h>
#include <jcl.h>
-#ifndef __GNUC__
- #ifndef __attribute__
- #define __attribute__(x) /* nothing */
- #endif
+#if !defined(__GNUC__) && !defined(__attribute__)
+# define __attribute__(x) /* nothing */
#endif
+#if SIZEOF_VOID_P == 8
+# define JCL_POINTER_CLASSNAME "gnu/classpath/Pointer64"
+# define JCL_POINTER_DATASIGN "J"
+# define JCL_POINTER_INTTYPE jlong
+# define JCL_POINTER_GETFIELD GetLongField
+#elif SIZEOF_VOID_P == 4
+# define JCL_POINTER_CLASSNAME "gnu/classpath/Pointer32"
+# define JCL_POINTER_DATASIGN "I"
+# define JCL_POINTER_INTTYPE jint
+# define JCL_POINTER_GETFIELD GetIntField
+#else
+# error "Pointer size is not supported."
+#endif /* SIZEOF_VOID_P */
+
/*
* Cached Pointer class info.
*/
@@ -55,6 +67,12 @@ static jclass rawDataClass = NULL;
static jfieldID rawData_fid = NULL;
static jmethodID rawData_mid = NULL;
+/* Define JCL_NO_JNIONLOAD to build JCL without JNI_OnLoad exported.
+ * (rawDataClass and friends are initialized lazily in that case.)
+ */
+
+#ifndef JCL_NO_JNIONLOAD
+
/*
* JNI OnLoad constructor.
*/
@@ -69,35 +87,23 @@ JNI_OnLoad (JavaVM *vm, void *reserved __attribute__((unused)))
return JNI_VERSION_1_4;
}
env = (JNIEnv *) envp;
-#if SIZEOF_VOID_P == 8
- rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer64");
- if (rawDataClass != NULL)
- rawDataClass = (*env)->NewGlobalRef (env, rawDataClass);
- if (rawDataClass != NULL)
- {
- rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data", "J");
- rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>", "(J)V");
- }
-#else
-#if SIZEOF_VOID_P == 4
- rawDataClass = (*env)->FindClass (env, "gnu/classpath/Pointer32");
+ rawDataClass = (*env)->FindClass (env, JCL_POINTER_CLASSNAME);
if (rawDataClass != NULL)
rawDataClass = (*env)->NewGlobalRef (env, rawDataClass);
if (rawDataClass != NULL)
{
- rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data", "I");
- rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>", "(I)V");
+ rawData_fid = (*env)->GetFieldID (env, rawDataClass, "data",
+ JCL_POINTER_DATASIGN);
+ rawData_mid = (*env)->GetMethodID (env, rawDataClass, "<init>",
+ "(" JCL_POINTER_DATASIGN ")V");
}
-#else
-#error "Pointer size is not supported."
-#endif /* SIZEOF_VOID_P == 4 */
-#endif /* SIZEOF_VOID_P == 8 */
return JNI_VERSION_1_4;
}
+#endif /* !JCL_NO_JNIONLOAD */
JNIEXPORT void JNICALL
JCL_ThrowException (JNIEnv * env, const char *className, const char *errMsg)
@@ -127,9 +133,10 @@ JCL_ThrowException (JNIEnv * env, const char *className, const char *errMsg)
}
/* Removed this (more comprehensive) error string to avoid the need for
* a static variable or allocation of a buffer for this message in this
- * (unlikely) error case. --Fridi.
+ * (unlikely) error case. --Fridi.
*
- * sprintf(errstr,"JCL: Failed to throw exception %s with message %s: could not find exception class.", className, errMsg);
+ * sprintf(errstr,"JCL: Failed to throw exception %s with message %s:"
+ * " could not find exception class.", className, errMsg);
*/
(*env)->ThrowNew (env, errExcClass, className);
}
@@ -154,12 +161,12 @@ JCL_realloc (JNIEnv * env, void *ptr, size_t size)
{
void *orig_ptr = ptr;
ptr = realloc (ptr, size);
- if (ptr == 0)
+ if (ptr == NULL)
{
- free (orig_ptr);
+ if (orig_ptr != NULL)
+ free (orig_ptr);
JCL_ThrowException (env, "java/lang/OutOfMemoryError",
"malloc() failed.");
- return NULL;
}
return (ptr);
}
@@ -238,37 +245,76 @@ JCL_FindClass (JNIEnv * env, const char *className)
/*
* Build a Pointer object.
*/
-
JNIEXPORT jobject JNICALL
JCL_NewRawDataObject (JNIEnv * env, void *data)
{
+#ifdef JCL_NO_JNIONLOAD
+ jclass aclass = rawDataClass;
+ jmethodID mid;
+ if (aclass == NULL)
+ {
+ aclass = (*env)->FindClass (env, JCL_POINTER_CLASSNAME);
+ if (aclass == NULL ||
+ (aclass = (*env)->NewGlobalRef (env, aclass)) == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Pointer class not found");
+ return NULL;
+ }
+ rawDataClass = aclass;
+ }
+ if ((mid = rawData_mid) == NULL)
+ {
+ if ((mid = (*env)->GetMethodID (env, aclass, "<init>",
+ "(" JCL_POINTER_DATASIGN ")V")) == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Pointer class constructor not found");
+ return NULL;
+ }
+ rawData_mid = mid;
+ }
+ return (*env)->NewObject (env, aclass, mid, (JCL_POINTER_INTTYPE) data);
+#else
if (rawDataClass == NULL || rawData_mid == NULL)
{
JCL_ThrowException (env, "java/lang/InternalError",
"Pointer class was not properly initialized");
return NULL;
}
-
-#if SIZEOF_VOID_P == 8
- return (*env)->NewObject (env, rawDataClass, rawData_mid, (jlong) data);
-#else
- return (*env)->NewObject (env, rawDataClass, rawData_mid, (jint) data);
+ return (*env)->NewObject (env, rawDataClass, rawData_mid,
+ (JCL_POINTER_INTTYPE) data);
#endif
}
JNIEXPORT void * JNICALL
JCL_GetRawData (JNIEnv * env, jobject rawdata)
{
+#ifdef JCL_NO_JNIONLOAD
+ jclass aclass;
+ jfieldID fid = rawData_fid;
+ if (fid == NULL)
+ {
+ aclass = rawDataClass;
+ if ((aclass == NULL && (aclass = (*env)->FindClass (env,
+ JCL_POINTER_CLASSNAME)) == NULL) ||
+ (fid = (*env)->GetFieldID (env, aclass, "data",
+ JCL_POINTER_DATASIGN)) == NULL)
+ {
+ JCL_ThrowException (env, "java/lang/InternalError",
+ "Pointer class was not properly initialized");
+ return NULL;
+ }
+ rawData_fid = fid;
+ }
+ return (void *) (*env)->JCL_POINTER_GETFIELD (env, rawdata, fid);
+#else
if (rawData_fid == NULL)
{
JCL_ThrowException (env, "java/lang/InternalError",
"Pointer class was not properly initialized");
return NULL;
}
-
-#if SIZEOF_VOID_P == 8
- return (void *) (*env)->GetLongField (env, rawdata, rawData_fid);
-#else
- return (void *) (*env)->GetIntField (env, rawdata, rawData_fid);
-#endif
+ return (void *) (*env)->JCL_POINTER_GETFIELD (env, rawdata, rawData_fid);
+#endif
}