OSDN Git Service

* prims.cc (_Jv_MallocUnchecked): New function.
authortromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Feb 2000 06:14:26 +0000 (06:14 +0000)
committertromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 1 Feb 2000 06:14:26 +0000 (06:14 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@31730 138bc75d-0d04-0410-961f-82ee72b054a4

libjava/ChangeLog
libjava/include/jni.h
libjava/include/jvm.h
libjava/jni.cc
libjava/prims.cc

index 6a7ba36..93db6e7 100644 (file)
@@ -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.
index 60b2302..c5ca7dc 100644 (file)
@@ -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); }
index a8d1fac..c9eb1b9 100644 (file)
@@ -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__ */
index e67bd8c..0b51fce 100644 (file)
@@ -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;
+
 \f
 
+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));
+}
+
+\f
+
+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);
 }
 
 \f
@@ -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);
 }
 
+\f
+
 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,
 
 \f
 
+// 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,
index 3c07644..5d72f15 100644 (file)
@@ -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
@@ -916,6 +918,14 @@ _Jv_SetMaximumHeapSize (const char *arg)
 \f
 
 void *
+_Jv_MallocUnchecked (jsize size)
+{
+  if (size == 0)
+    size = 1;
+  return malloc ((size_t) size);
+}
+
+void *
 _Jv_Malloc (jsize size)
 {
   if (size == 0)