OSDN Git Service

* libjava.verify/verify.exp: New file.
[pf3gnuchains/gcc-fork.git] / libjava / interpret.cc
index e5c40cf..43d6279 100644 (file)
@@ -1,6 +1,6 @@
 // interpret.cc - Code for the interpreter
 
-/* Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003 Free Software Foundation
 
    This file is part of libgcj.
 
@@ -22,7 +22,6 @@ details.  */
 #include <jvm.h>
 #include <java-cpool.h>
 #include <java-interp.h>
-// #include <java/lang/fdlibm.h>
 #include <java/lang/System.h>
 #include <java/lang/String.h>
 #include <java/lang/Integer.h>
@@ -36,6 +35,7 @@ details.  */
 #include <java/lang/NullPointerException.h>
 #include <java/lang/ArithmeticException.h>
 #include <java/lang/IncompatibleClassChangeError.h>
+#include <java/lang/Thread.h>
 #include <java-insns.h>
 #include <java-signal.h>
 
@@ -91,7 +91,7 @@ static inline void dupx (_Jv_word *sp, int n, int x)
       sp[top-(n+x)-i] = sp[top-i];
     }
   
-};
+}
 
 // Used to convert from floating types to integral types.
 template<typename TO, typename FROM>
@@ -240,19 +240,21 @@ static jint get4(unsigned char* loc) {
     }                                                                        \
   while (0)
 
-void _Jv_InterpMethod::run_normal (ffi_cif *,
-                                  void* ret,
-                                  ffi_raw * args,
-                                  void* __this)
+void
+_Jv_InterpMethod::run_normal (ffi_cif *,
+                             void* ret,
+                             ffi_raw * args,
+                             void* __this)
 {
   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
   _this->run (ret, args);
 }
 
-void _Jv_InterpMethod::run_synch_object (ffi_cif *,
-                                        void* ret,
-                                        ffi_raw * args,
-                                        void* __this)
+void
+_Jv_InterpMethod::run_synch_object (ffi_cif *,
+                                   void* ret,
+                                   ffi_raw * args,
+                                   void* __this)
 {
   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
 
@@ -262,14 +264,27 @@ void _Jv_InterpMethod::run_synch_object (ffi_cif *,
   _this->run (ret, args);
 }
 
-void _Jv_InterpMethod::run_synch_class (ffi_cif *,
-                                       void* ret,
-                                       ffi_raw * args,
-                                       void* __this)
+void
+_Jv_InterpMethod::run_class (ffi_cif *,
+                            void* ret,
+                            ffi_raw * args,
+                            void* __this)
+{
+  _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
+  _Jv_InitClass (_this->defining_class);
+  _this->run (ret, args);
+}
+
+void
+_Jv_InterpMethod::run_synch_class (ffi_cif *,
+                                  void* ret,
+                                  ffi_raw * args,
+                                  void* __this)
 {
   _Jv_InterpMethod *_this = (_Jv_InterpMethod *) __this;
 
   jclass sync = _this->defining_class;
+  _Jv_InitClass (sync);
   JvSynchronize mutex (sync);
 
   _this->run (ret, args);
@@ -312,7 +327,7 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
 
       if (! first_pass)
        {
-         insns = (insn_slot *) _Jv_Malloc (sizeof (insn_slot) * next);
+         insns = (insn_slot *) _Jv_AllocBytes (sizeof (insn_slot) * next);
          next = 0;
        }
 
@@ -744,11 +759,28 @@ _Jv_InterpMethod::compile (const void * const *insn_targets)
 }
 #endif /* DIRECT_THREADED */
 
+// This function exists so that the stack-tracing code can find the
+// boundaries of the interpreter.
+void
+_Jv_StartOfInterpreter (void)
+{
+}
+
 void
 _Jv_InterpMethod::run (void *retp, ffi_raw *args)
 {
   using namespace java::lang::reflect;
 
+  // FRAME_DESC registers this particular invocation as the top-most
+  // interpreter frame.  This lets the stack tracing code (for
+  // Throwable) print information about the method being interpreted
+  // rather than about the interpreter itself.  FRAME_DESC has a
+  // destructor so it cleans up automatically when the interpreter
+  // returns.
+  java::lang::Thread *thread = java::lang::Thread::currentThread();
+  _Jv_MethodChain frame_desc (this,
+                             (_Jv_MethodChain **) &thread->interp_frame);
+
   _Jv_word stack[max_stack];
   _Jv_word *sp = stack;
 
@@ -1866,7 +1898,7 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
     insn_iushr:
       {
        jint shift = (POPI() & 0x1f);
-       unsigned long value = POPI();
+       UINT32 value = (UINT32) POPI();
        PUSHI ((jint) (value >> shift));
       }
       NEXT_INSN;
@@ -2778,7 +2810,10 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
 
        sp -= rmeth->stack_item_count;
 
-       NULLCHECK (sp[0].o);
+       // We don't use NULLCHECK here because we can't rely on that
+       // working for <init>.  So instead we do an explicit test.
+       if (! sp[0].o)
+         throw new java::lang::NullPointerException;
 
        fun = (void (*)()) rmeth->method->ncode;
 
@@ -2796,7 +2831,10 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
       {
        rmeth = (_Jv_ResolvedMethod *) AVAL ();
        sp -= rmeth->stack_item_count;
-       NULLCHECK (sp[0].o);
+       // We don't use NULLCHECK here because we can't rely on that
+       // working for <init>.  So instead we do an explicit test.
+       if (! sp[0].o)
+         throw new java::lang::NullPointerException;
        fun = (void (*)()) rmeth->method->ncode;
       }
       goto perform_invoke;
@@ -2810,7 +2848,6 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
 
        sp -= rmeth->stack_item_count;
 
-       _Jv_InitClass (rmeth->klass);
        fun = (void (*)()) rmeth->method->ncode;
 
 #ifdef DIRECT_THREADED
@@ -2880,6 +2917,9 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
       {
        int index = GET2U ();
        jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
+       // We initialize here because otherwise `size_in_bytes' may
+       // not be set correctly, leading us to pass `0' as the size.
+       // FIXME: fix in the allocator?  There is a PR for this.
        _Jv_InitClass (klass);
        jobject res = _Jv_AllocObject (klass, klass->size_in_bytes);
        PUSHA (res);
@@ -2915,7 +2955,6 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
        int index = GET2U ();
        jclass klass = (_Jv_ResolvePoolEntry (defining_class, index)).clazz;
        int size  = POPI();
-       _Jv_InitClass (klass);
        jobject result = _Jv_NewObjectArray (size, klass, 0);
        PUSHA (result);
 
@@ -3049,7 +3088,6 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
 
        jclass type    
          = (_Jv_ResolvePoolEntry (defining_class, kind_index)).clazz;
-       _Jv_InitClass (type);
        jint *sizes    = (jint*) __builtin_alloca (sizeof (jint)*dim);
 
        for (int i = dim - 1; i >= 0; i--)
@@ -3169,6 +3207,13 @@ _Jv_InterpMethod::run (void *retp, ffi_raw *args)
     }
 }
 
+// This function exists so that the stack-tracing code can find the
+// boundaries of the interpreter.
+void
+_Jv_EndOfInterpreter (void)
+{
+}
+
 static void
 throw_internal_error (char *msg)
 {