prims.cc (_Jv_MallocUnchecked): New function.
* prims.cc (_Jv_MallocUnchecked): New function. (main_init): Call _Jv_JNI_Init. * include/jvm.h (_Jv_MallocUnchecked): Declare. (_Jv_JNI_Init): Declare. * jni.cc: Include Hashtable.h, OutOfMemoryError.h, Integer.h, <string.h>. (_Jv_JNI_NewGlobalRef): New function. (_Jv_JNI_DeleteGlobalRef): New function. (_Jv_JNI_DeleteLocalRef): New function. (_Jv_JNI_conversion_call): Initialize and clear local reference frame. (_Jv_JNI_NewLocalRef): New function. (struct _Jv_JNI_LocalFrame): New structure. (_Jv_JNI_PushLocalFrame): New function. (_Jv_JNI_EnsureLocalCapacity): New function. (FRAME_SIZE): New define. (_Jv_JNI_GetStringChars): Mark string, not characters. (_Jv_JNI_ReleaseStringChars): Unmark string, not characters. (_Jv_JNI_GetPrimitiveArrayElements): Mark array, not elements. (_Jv_JNI_ReleasePrimitiveArrayElements): Unmark array, not elements. (_Jv_JNI_DefineClass): Make return value a local ref. (_Jv_JNI_FindClass): Likewise. (_Jv_JNI_GetSuperclass): Likewise. (_Jv_JNI_ExceptionOccurred): Likewise. (_Jv_JNI_AllocObject): Likewise. (_Jv_JNI_GetObjectClass): Likewise. (_Jv_JNI_CallAnyMethodV): Likewise. (_Jv_JNI_NewString): Likewise. (_Jv_JNI_NewStringUTF): Likewise. (_Jv_JNI_NewObjectArray): Likewise. (_Jv_JNI_GetObjectArrayElement): Likewise. (_Jv_JNI_ToReflectedField): Likewise. (_Jv_JNI_ToReflectedMethod): Likewise. (_Jv_JNIFunctions): Updated table for new functions. (_Jv_JNI_Init): New function. (mark_for_gc): Wrote. (unmark_for_gc): Wrote. * include/jni.h (struct JNINativeInterface): Removed name from PopLocalFrame parameter. (class _Jv_JNIEnv): Added `locals' field. From-SVN: r31730
This commit is contained in:
parent
07a3462a53
commit
7e648cf954
@ -1,3 +1,47 @@
|
||||
2000-01-31 Tom Tromey <tromey@cygnus.com>
|
||||
|
||||
* prims.cc (_Jv_MallocUnchecked): New function.
|
||||
(main_init): Call _Jv_JNI_Init.
|
||||
* include/jvm.h (_Jv_MallocUnchecked): Declare.
|
||||
(_Jv_JNI_Init): Declare.
|
||||
* jni.cc: Include Hashtable.h, OutOfMemoryError.h, Integer.h,
|
||||
<string.h>.
|
||||
(_Jv_JNI_NewGlobalRef): New function.
|
||||
(_Jv_JNI_DeleteGlobalRef): New function.
|
||||
(_Jv_JNI_DeleteLocalRef): New function.
|
||||
(_Jv_JNI_conversion_call): Initialize and clear local reference
|
||||
frame.
|
||||
(_Jv_JNI_NewLocalRef): New function.
|
||||
(struct _Jv_JNI_LocalFrame): New structure.
|
||||
(_Jv_JNI_PushLocalFrame): New function.
|
||||
(_Jv_JNI_EnsureLocalCapacity): New function.
|
||||
(FRAME_SIZE): New define.
|
||||
(_Jv_JNI_GetStringChars): Mark string, not characters.
|
||||
(_Jv_JNI_ReleaseStringChars): Unmark string, not characters.
|
||||
(_Jv_JNI_GetPrimitiveArrayElements): Mark array, not elements.
|
||||
(_Jv_JNI_ReleasePrimitiveArrayElements): Unmark array, not
|
||||
elements.
|
||||
(_Jv_JNI_DefineClass): Make return value a local ref.
|
||||
(_Jv_JNI_FindClass): Likewise.
|
||||
(_Jv_JNI_GetSuperclass): Likewise.
|
||||
(_Jv_JNI_ExceptionOccurred): Likewise.
|
||||
(_Jv_JNI_AllocObject): Likewise.
|
||||
(_Jv_JNI_GetObjectClass): Likewise.
|
||||
(_Jv_JNI_CallAnyMethodV): Likewise.
|
||||
(_Jv_JNI_NewString): Likewise.
|
||||
(_Jv_JNI_NewStringUTF): Likewise.
|
||||
(_Jv_JNI_NewObjectArray): Likewise.
|
||||
(_Jv_JNI_GetObjectArrayElement): Likewise.
|
||||
(_Jv_JNI_ToReflectedField): Likewise.
|
||||
(_Jv_JNI_ToReflectedMethod): Likewise.
|
||||
(_Jv_JNIFunctions): Updated table for new functions.
|
||||
(_Jv_JNI_Init): New function.
|
||||
(mark_for_gc): Wrote.
|
||||
(unmark_for_gc): Wrote.
|
||||
* include/jni.h (struct JNINativeInterface): Removed name from
|
||||
PopLocalFrame parameter.
|
||||
(class _Jv_JNIEnv): Added `locals' field.
|
||||
|
||||
Mon Jan 31 00:43:15 2000 Anthony Green <green@redhat.com>
|
||||
|
||||
* gnu/gcj/convert/natIconv.cc (read): Minor fixes.
|
||||
|
@ -133,7 +133,7 @@ struct JNINativeInterface
|
||||
void (*FatalError) (JNIEnv *, const char *);
|
||||
|
||||
jint (*PushLocalFrame) (JNIEnv *, jint);
|
||||
jobject (*PopLocalFrame) (JNIEnv *, jobject result);
|
||||
jobject (*PopLocalFrame) (JNIEnv *, jobject);
|
||||
|
||||
jobject (*NewGlobalRef) (JNIEnv *, jobject);
|
||||
void (*DeleteGlobalRef) (JNIEnv *, jobject);
|
||||
@ -538,6 +538,9 @@ private:
|
||||
/* The class of the current native method. */
|
||||
jclass klass;
|
||||
|
||||
/* The chain of local frames. */
|
||||
struct _Jv_JNI_LocalFrame *locals;
|
||||
|
||||
public:
|
||||
jclass GetSuperclass (jclass cl)
|
||||
{ return p->GetSuperclass (this, cl); }
|
||||
|
@ -72,6 +72,10 @@ void _Jv_InitGC (void);
|
||||
/* Register a finalizer. */
|
||||
void _Jv_RegisterFinalizer (void *object, _Jv_FinalizerFunc *method);
|
||||
|
||||
/* Allocate some unscanned, unmoveable memory. Return NULL if out of
|
||||
memory. */
|
||||
void *_Jv_MallocUnchecked (jsize size) __attribute__((__malloc__));
|
||||
|
||||
/* Run finalizers for objects ready to be finalized.. */
|
||||
void _Jv_RunFinalizers (void);
|
||||
/* Run all finalizers. Should be called only before exit. */
|
||||
@ -197,4 +201,8 @@ extern "C"
|
||||
extern char *_Jv_ThisExecutable (void);
|
||||
extern void _Jv_ThisExecutable (const char *);
|
||||
|
||||
/* Initialize JNI. */
|
||||
extern void _Jv_JNI_Init (void);
|
||||
|
||||
|
||||
#endif /* __JAVA_JVM_H__ */
|
||||
|
312
libjava/jni.cc
312
libjava/jni.cc
@ -17,6 +17,7 @@ details. */
|
||||
#include <config.h>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
// Define this before including jni.h.
|
||||
#define __GCJ_JNI_IMPL__
|
||||
@ -37,6 +38,9 @@ details. */
|
||||
#include <java/lang/reflect/Constructor.h>
|
||||
#include <java/lang/reflect/Method.h>
|
||||
#include <java/lang/reflect/Modifier.h>
|
||||
#include <java/lang/OutOfMemoryError.h>
|
||||
#include <java/util/Hashtable.h>
|
||||
#include <java/lang/Integer.h>
|
||||
|
||||
#include <gcj/method.h>
|
||||
#include <gcj/field.h>
|
||||
@ -62,20 +66,202 @@ enum invocation_type
|
||||
// Forward declaration.
|
||||
extern struct JNINativeInterface _Jv_JNIFunctions;
|
||||
|
||||
// Number of slots in the default frame. The VM must allow at least
|
||||
// 16.
|
||||
#define FRAME_SIZE 32
|
||||
|
||||
// This structure is used to keep track of local references.
|
||||
struct _Jv_JNI_LocalFrame
|
||||
{
|
||||
// This is true if this frame object represents a pushed frame (eg
|
||||
// from PushLocalFrame).
|
||||
int marker : 1;
|
||||
|
||||
// Number of elements in frame.
|
||||
int size : 31;
|
||||
|
||||
// Next frame in chain.
|
||||
_Jv_JNI_LocalFrame *next;
|
||||
|
||||
// The elements. These are allocated using the C "struct hack".
|
||||
jobject vec[0];
|
||||
};
|
||||
|
||||
// This holds a reference count for all local and global references.
|
||||
static java::util::Hashtable *ref_table;
|
||||
|
||||
|
||||
|
||||
void
|
||||
_Jv_JNI_Init (void)
|
||||
{
|
||||
ref_table = new java::util::Hashtable;
|
||||
}
|
||||
|
||||
// Tell the GC that a certain pointer is live.
|
||||
static void
|
||||
mark_for_gc (void *)
|
||||
mark_for_gc (jobject obj)
|
||||
{
|
||||
// FIXME.
|
||||
JvSynchronize sync (ref_table);
|
||||
|
||||
using namespace java::lang;
|
||||
Integer *refcount = (Integer *) ref_table->get (obj);
|
||||
jint val = (refcount == NULL) ? 0 : refcount->intValue ();
|
||||
ref_table->put (obj, new Integer (val + 1));
|
||||
}
|
||||
|
||||
// Unmark a pointer.
|
||||
static void
|
||||
unmark_for_gc (void *)
|
||||
unmark_for_gc (jobject obj)
|
||||
{
|
||||
// FIXME.
|
||||
JvSynchronize sync (ref_table);
|
||||
|
||||
using namespace java::lang;
|
||||
Integer *refcount = (Integer *) ref_table->get (obj);
|
||||
JvAssert (refcount);
|
||||
jint val = refcount->intValue () - 1;
|
||||
if (val == 0)
|
||||
ref_table->remove (obj);
|
||||
else
|
||||
ref_table->put (obj, new Integer (val));
|
||||
}
|
||||
|
||||
|
||||
|
||||
static jobject
|
||||
_Jv_JNI_NewGlobalRef (JNIEnv *, jobject obj)
|
||||
{
|
||||
mark_for_gc (obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static void
|
||||
_Jv_JNI_DeleteGlobalRef (JNIEnv *, jobject obj)
|
||||
{
|
||||
unmark_for_gc (obj);
|
||||
}
|
||||
|
||||
static void
|
||||
_Jv_JNI_DeleteLocalRef (JNIEnv *env, jobject obj)
|
||||
{
|
||||
_Jv_JNI_LocalFrame *frame;
|
||||
|
||||
for (frame = env->locals; frame != NULL; frame = frame->next)
|
||||
{
|
||||
for (int i = 0; i < FRAME_SIZE; ++i)
|
||||
{
|
||||
if (frame->vec[i] == obj)
|
||||
{
|
||||
frame->vec[i] = NULL;
|
||||
unmark_for_gc (obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Don't go past a marked frame.
|
||||
JvAssert (! frame->marker);
|
||||
}
|
||||
|
||||
JvAssert (0);
|
||||
}
|
||||
|
||||
static jint
|
||||
_Jv_JNI_EnsureLocalCapacity (JNIEnv *env, jint size)
|
||||
{
|
||||
// It is easier to just always allocate a new frame of the requested
|
||||
// size. This isn't the most efficient thing, but for now we don't
|
||||
// care. Note that _Jv_JNI_PushLocalFrame relies on this right now.
|
||||
|
||||
_Jv_JNI_LocalFrame *frame
|
||||
= (_Jv_JNI_LocalFrame *) _Jv_MallocUnchecked (sizeof (_Jv_JNI_LocalFrame)
|
||||
+ size * sizeof (jobject));
|
||||
if (frame == NULL)
|
||||
{
|
||||
// FIXME: exception processing.
|
||||
env->ex = new java::lang::OutOfMemoryError;
|
||||
return -1;
|
||||
}
|
||||
|
||||
frame->marker = true;
|
||||
frame->size = size;
|
||||
memset (&frame->vec[0], 0, size * sizeof (jobject));
|
||||
frame->next = env->locals;
|
||||
env->locals = frame;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static jint
|
||||
_Jv_JNI_PushLocalFrame (JNIEnv *env, jint size)
|
||||
{
|
||||
jint r = _Jv_JNI_EnsureLocalCapacity (env, size);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
// The new frame is on top.
|
||||
env->locals->marker = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static jobject
|
||||
_Jv_JNI_NewLocalRef (JNIEnv *env, jobject obj)
|
||||
{
|
||||
// Try to find an open slot somewhere in the topmost frame.
|
||||
_Jv_JNI_LocalFrame *frame = env->locals;
|
||||
bool done = false, set = false;
|
||||
while (frame != NULL && ! done)
|
||||
{
|
||||
for (int i = 0; i < frame->size; ++i)
|
||||
if (frame->vec[i] == NULL)
|
||||
{
|
||||
set = true;
|
||||
done = true;
|
||||
frame->vec[i] = obj;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (! set)
|
||||
{
|
||||
// No slots, so we allocate a new frame. According to the spec
|
||||
// we could just die here. FIXME: return value.
|
||||
_Jv_JNI_EnsureLocalCapacity (env, 16);
|
||||
// We know the first element of the new frame will be ok.
|
||||
env->locals->vec[0] = obj;
|
||||
}
|
||||
|
||||
mark_for_gc (obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
static jobject
|
||||
_Jv_JNI_PopLocalFrame (JNIEnv *env, jobject result)
|
||||
{
|
||||
_Jv_JNI_LocalFrame *rf = env->locals;
|
||||
|
||||
bool done = false;
|
||||
while (rf != NULL && ! done)
|
||||
{
|
||||
for (int i = 0; i < rf->size; ++i)
|
||||
if (rf->vec[i] != NULL)
|
||||
unmark_for_gc (rf->vec[i]);
|
||||
|
||||
// If the frame we just freed is the marker frame, we are done.
|
||||
done = rf->marker;
|
||||
|
||||
_Jv_JNI_LocalFrame *n = rf->next;
|
||||
// When N==NULL, we've reached the stack-allocated frame, and we
|
||||
// must not free it. However, we must be sure to clear all its
|
||||
// elements, since we might conceivably reuse it.
|
||||
if (n == NULL)
|
||||
memset (&rf->vec[0], 0, rf->size * sizeof (jobject));
|
||||
else
|
||||
_Jv_Free (rf);
|
||||
rf = n;
|
||||
}
|
||||
|
||||
return result == NULL ? NULL : _Jv_JNI_NewLocalRef (env, result);
|
||||
}
|
||||
|
||||
|
||||
@ -87,7 +273,7 @@ _Jv_JNI_GetVersion (JNIEnv *)
|
||||
}
|
||||
|
||||
static jclass
|
||||
_Jv_JNI_DefineClass (JNIEnv *, jobject loader,
|
||||
_Jv_JNI_DefineClass (JNIEnv *env, jobject loader,
|
||||
const jbyte *buf, jsize bufLen)
|
||||
{
|
||||
jbyteArray bytes = JvNewByteArray (bufLen);
|
||||
@ -99,7 +285,7 @@ _Jv_JNI_DefineClass (JNIEnv *, jobject loader,
|
||||
|
||||
// FIXME: exception processing.
|
||||
jclass result = l->defineClass (bytes, 0, bufLen);
|
||||
return result;
|
||||
return (jclass) _Jv_JNI_NewLocalRef (env, result);
|
||||
}
|
||||
|
||||
static jclass
|
||||
@ -125,13 +311,13 @@ _Jv_JNI_FindClass (JNIEnv *env, const char *name)
|
||||
// FIXME: exception processing.
|
||||
jclass r = loader->findClass (n);
|
||||
|
||||
return r;
|
||||
return (jclass) _Jv_JNI_NewLocalRef (env, r);
|
||||
}
|
||||
|
||||
static jclass
|
||||
_Jv_JNI_GetSuperclass (JNIEnv *, jclass clazz)
|
||||
_Jv_JNI_GetSuperclass (JNIEnv *env, jclass clazz)
|
||||
{
|
||||
return clazz->getSuperclass ();
|
||||
return (jclass) _Jv_JNI_NewLocalRef (env, clazz->getSuperclass ());
|
||||
}
|
||||
|
||||
static jboolean
|
||||
@ -175,8 +361,7 @@ _Jv_JNI_ThrowNew (JNIEnv *env, jclass clazz, const char *message)
|
||||
static jthrowable
|
||||
_Jv_JNI_ExceptionOccurred (JNIEnv *env)
|
||||
{
|
||||
// FIXME: create local reference.
|
||||
return env->ex;
|
||||
return (jthrowable) _Jv_JNI_NewLocalRef (env, env->ex);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -204,6 +389,8 @@ _Jv_JNI_FatalError (JNIEnv *, const char *message)
|
||||
JvFail (message);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static jboolean
|
||||
_Jv_JNI_IsSameObject (JNIEnv *, jobject obj1, jobject obj2)
|
||||
{
|
||||
@ -224,13 +411,13 @@ _Jv_JNI_AllocObject (JNIEnv *env, jclass clazz)
|
||||
obj = JvAllocObject (clazz);
|
||||
}
|
||||
|
||||
return obj;
|
||||
return _Jv_JNI_NewLocalRef (env, obj);
|
||||
}
|
||||
|
||||
static jclass
|
||||
_Jv_JNI_GetObjectClass (JNIEnv *, jobject obj)
|
||||
_Jv_JNI_GetObjectClass (JNIEnv *env, jobject obj)
|
||||
{
|
||||
return obj->getClass();
|
||||
return (jclass) _Jv_JNI_NewLocalRef (env, obj->getClass());
|
||||
}
|
||||
|
||||
static jboolean
|
||||
@ -346,6 +533,14 @@ _Jv_JNI_CallAnyMethodV (JNIEnv *env, jobject obj, jclass klass,
|
||||
if (ex != NULL)
|
||||
env->ex = ex;
|
||||
|
||||
if (! return_type->isPrimitive ())
|
||||
{
|
||||
// Make sure we create a local reference. The cast hackery is
|
||||
// to avoid problems for template instantations we know won't be
|
||||
// used.
|
||||
return (T) (long long) _Jv_JNI_NewLocalRef (env, result.l);
|
||||
}
|
||||
|
||||
// We cheat a little here. FIXME.
|
||||
return * (T *) &result;
|
||||
}
|
||||
@ -390,6 +585,14 @@ _Jv_JNI_CallAnyMethodA (JNIEnv *env, jobject obj, jclass klass,
|
||||
if (ex != NULL)
|
||||
env->ex = ex;
|
||||
|
||||
if (! return_type->isPrimitive ())
|
||||
{
|
||||
// Make sure we create a local reference. The cast hackery is
|
||||
// to avoid problems for template instantations we know won't be
|
||||
// used.
|
||||
return (T) (long long) _Jv_JNI_NewLocalRef (env, result.l);
|
||||
}
|
||||
|
||||
// We cheat a little here. FIXME.
|
||||
return * (T *) &result;
|
||||
}
|
||||
@ -608,6 +811,7 @@ _Jv_JNI_NewObjectA (JNIEnv *env, jclass klass, jmethodID id,
|
||||
|
||||
|
||||
|
||||
// FIXME: local reference
|
||||
template<typename T>
|
||||
static T
|
||||
_Jv_JNI_GetField (JNIEnv *, jobject obj, jfieldID field)
|
||||
@ -675,6 +879,7 @@ _Jv_JNI_GetAnyFieldID (JNIEnv *env, jclass clazz,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FIXME: local reference
|
||||
template<typename T>
|
||||
static T
|
||||
_Jv_JNI_GetStaticField (JNIEnv *, jclass, jfieldID field)
|
||||
@ -692,11 +897,11 @@ _Jv_JNI_SetStaticField (JNIEnv *, jclass, jfieldID field, T value)
|
||||
}
|
||||
|
||||
static jstring
|
||||
_Jv_JNI_NewString (JNIEnv *, const jchar *unichars, jsize len)
|
||||
_Jv_JNI_NewString (JNIEnv *env, const jchar *unichars, jsize len)
|
||||
{
|
||||
// FIXME: exception processing.
|
||||
jstring r = _Jv_NewString (unichars, len);
|
||||
return r;
|
||||
return (jstring) _Jv_JNI_NewLocalRef (env, r);
|
||||
}
|
||||
|
||||
static jsize
|
||||
@ -709,24 +914,24 @@ static const jchar *
|
||||
_Jv_JNI_GetStringChars (JNIEnv *, jstring string, jboolean *isCopy)
|
||||
{
|
||||
jchar *result = _Jv_GetStringChars (string);
|
||||
mark_for_gc (result);
|
||||
mark_for_gc (string);
|
||||
if (isCopy)
|
||||
*isCopy = false;
|
||||
return (const jchar *) result;
|
||||
}
|
||||
|
||||
static void
|
||||
_Jv_JNI_ReleaseStringChars (JNIEnv *, jstring, const jchar *chars)
|
||||
_Jv_JNI_ReleaseStringChars (JNIEnv *, jstring string, const jchar *)
|
||||
{
|
||||
unmark_for_gc ((void *) chars);
|
||||
unmark_for_gc (string);
|
||||
}
|
||||
|
||||
static jstring
|
||||
_Jv_JNI_NewStringUTF (JNIEnv *, const char *bytes)
|
||||
_Jv_JNI_NewStringUTF (JNIEnv *env, const char *bytes)
|
||||
{
|
||||
// FIXME: exception processing.
|
||||
jstring r = JvNewStringUTF (bytes);
|
||||
return r;
|
||||
jstring result = JvNewStringUTF (bytes);
|
||||
return (jstring) _Jv_JNI_NewLocalRef (env, result);
|
||||
}
|
||||
|
||||
static jsize
|
||||
@ -801,19 +1006,19 @@ _Jv_JNI_GetArrayLength (JNIEnv *, jarray array)
|
||||
}
|
||||
|
||||
static jarray
|
||||
_Jv_JNI_NewObjectArray (JNIEnv *, jsize length, jclass elementClass,
|
||||
_Jv_JNI_NewObjectArray (JNIEnv *env, jsize length, jclass elementClass,
|
||||
jobject init)
|
||||
{
|
||||
// FIXME: exception processing.
|
||||
jarray result = JvNewObjectArray (length, elementClass, init);
|
||||
return result;
|
||||
return (jarray) _Jv_JNI_NewLocalRef (env, result);
|
||||
}
|
||||
|
||||
static jobject
|
||||
_Jv_JNI_GetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index)
|
||||
_Jv_JNI_GetObjectArrayElement (JNIEnv *env, jobjectArray array, jsize index)
|
||||
{
|
||||
jobject *elts = elements (array);
|
||||
return elts[index];
|
||||
return _Jv_JNI_NewLocalRef (env, elts[index]);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -828,9 +1033,11 @@ _Jv_JNI_SetObjectArrayElement (JNIEnv *, jobjectArray array, jsize index,
|
||||
|
||||
template<typename T, jclass K>
|
||||
static JArray<T> *
|
||||
_Jv_JNI_NewPrimitiveArray (JNIEnv *, jsize length)
|
||||
_Jv_JNI_NewPrimitiveArray (JNIEnv *env, jsize length)
|
||||
{
|
||||
return (JArray<T> *) _Jv_NewPrimArray (K, length);
|
||||
// FIXME: exception processing.
|
||||
return (JArray<T> *) _Jv_JNI_NewLocalRef (env,
|
||||
_Jv_NewPrimArray (K, length));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -844,19 +1051,19 @@ _Jv_JNI_GetPrimitiveArrayElements (JNIEnv *, JArray<T> *array,
|
||||
// We elect never to copy.
|
||||
*isCopy = false;
|
||||
}
|
||||
mark_for_gc (elts);
|
||||
mark_for_gc (array);
|
||||
return elts;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static void
|
||||
_Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *,
|
||||
T *elems, jint /* mode */)
|
||||
_Jv_JNI_ReleasePrimitiveArrayElements (JNIEnv *, JArray<T> *array,
|
||||
T *, jint /* mode */)
|
||||
{
|
||||
// Note that we ignore MODE. We can do this because we never copy
|
||||
// the array elements. My reading of the JNI documentation is that
|
||||
// this is an option for the implementor.
|
||||
unmark_for_gc (elems);
|
||||
unmark_for_gc (array);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
@ -931,7 +1138,7 @@ _Jv_JNI_MonitorExit (JNIEnv *, jobject obj)
|
||||
|
||||
// JDK 1.2
|
||||
jobject
|
||||
_Jv_JNI_ToReflectedField (JNIEnv *, jclass cls, jfieldID fieldID,
|
||||
_Jv_JNI_ToReflectedField (JNIEnv *env, jclass cls, jfieldID fieldID,
|
||||
jboolean)
|
||||
{
|
||||
// FIXME: exception processing.
|
||||
@ -939,8 +1146,7 @@ _Jv_JNI_ToReflectedField (JNIEnv *, jclass cls, jfieldID fieldID,
|
||||
field->declaringClass = cls;
|
||||
field->offset = (char*) fieldID - (char *) cls->fields;
|
||||
field->name = _Jv_NewStringUtf8Const (fieldID->getNameUtf8Const (cls));
|
||||
// FIXME: make a local reference.
|
||||
return field;
|
||||
return _Jv_JNI_NewLocalRef (env, field);
|
||||
}
|
||||
|
||||
// JDK 1.2
|
||||
@ -954,7 +1160,7 @@ _Jv_JNI_FromReflectedField (JNIEnv *, jobject f)
|
||||
}
|
||||
|
||||
jobject
|
||||
_Jv_JNI_ToReflectedMethod (JNIEnv *, jclass klass, jmethodID id,
|
||||
_Jv_JNI_ToReflectedMethod (JNIEnv *env, jclass klass, jmethodID id,
|
||||
jboolean)
|
||||
{
|
||||
using namespace java::lang::reflect;
|
||||
@ -979,8 +1185,7 @@ _Jv_JNI_ToReflectedMethod (JNIEnv *, jclass klass, jmethodID id,
|
||||
result = meth;
|
||||
}
|
||||
|
||||
// FIXME: make a local reference.
|
||||
return result;
|
||||
return _Jv_JNI_NewLocalRef (env, result);
|
||||
}
|
||||
|
||||
static jmethodID
|
||||
@ -1003,13 +1208,26 @@ static T
|
||||
_Jv_JNI_conversion_call (fixme)
|
||||
{
|
||||
JNIEnv env;
|
||||
_Jv_JNI_LocalFrame *frame
|
||||
= (_Jv_JNI_LocalFrame *) alloca (sizeof (_Jv_JNI_LocalFrame)
|
||||
+ FRAME_SIZE * sizeof (jobject));
|
||||
|
||||
env.p = &_Jv_JNIFunctions;
|
||||
env.ex = NULL;
|
||||
env.klass = FIXME;
|
||||
env.locals = frame;
|
||||
|
||||
frame->marker = true;
|
||||
frame->next = NULL;
|
||||
frame->size = FRAME_SIZE;
|
||||
for (int i = 0; i < frame->size; ++i)
|
||||
frame->vec[i] = NULL;
|
||||
|
||||
T result = FIXME_ffi_call (args);
|
||||
|
||||
while (env.locals != NULL)
|
||||
_Jv_JNI_PopLocalFrame (&env, result);
|
||||
|
||||
if (env.ex)
|
||||
JvThrow (env.ex);
|
||||
|
||||
@ -1043,14 +1261,18 @@ struct JNINativeInterface _Jv_JNIFunctions =
|
||||
_Jv_JNI_ExceptionDescribe,
|
||||
_Jv_JNI_ExceptionClear,
|
||||
_Jv_JNI_FatalError,
|
||||
NOT_IMPL,
|
||||
NOT_IMPL,
|
||||
NOT_IMPL /* NewGlobalRef */,
|
||||
NOT_IMPL /* DeleteGlobalRef */,
|
||||
NOT_IMPL /* DeleteLocalRef */,
|
||||
|
||||
_Jv_JNI_PushLocalFrame,
|
||||
_Jv_JNI_PopLocalFrame,
|
||||
_Jv_JNI_NewGlobalRef,
|
||||
_Jv_JNI_DeleteGlobalRef,
|
||||
_Jv_JNI_DeleteLocalRef,
|
||||
|
||||
_Jv_JNI_IsSameObject,
|
||||
NOT_IMPL,
|
||||
NOT_IMPL,
|
||||
|
||||
_Jv_JNI_NewLocalRef,
|
||||
_Jv_JNI_EnsureLocalCapacity,
|
||||
|
||||
_Jv_JNI_AllocObject,
|
||||
_Jv_JNI_NewObject,
|
||||
_Jv_JNI_NewObjectV,
|
||||
|
@ -687,6 +687,8 @@ main_init ()
|
||||
sigemptyset (&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
sigaction (SIGPIPE, &act, NULL);
|
||||
|
||||
_Jv_JNI_Init ();
|
||||
}
|
||||
|
||||
#ifndef DISABLE_GETENV_PROPERTIES
|
||||
@ -915,6 +917,14 @@ _Jv_SetMaximumHeapSize (const char *arg)
|
||||
|
||||
|
||||
|
||||
void *
|
||||
_Jv_MallocUnchecked (jsize size)
|
||||
{
|
||||
if (size == 0)
|
||||
size = 1;
|
||||
return malloc ((size_t) size);
|
||||
}
|
||||
|
||||
void *
|
||||
_Jv_Malloc (jsize size)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user