OSDN Git Service

* config/avr/avr.md ("call_prologue_saves"): Use hi8(gs())/lo8(gs())
[pf3gnuchains/gcc-fork.git] / libjava / link.cc
index 1d873ac..f995531 100644 (file)
@@ -1,6 +1,7 @@
 // link.cc - Code for linking and resolving classes and pool entries.
 
-/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation
+/* Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
+   Free Software Foundation
 
    This file is part of libgcj.
 
@@ -33,8 +34,10 @@ details.  */
 #include <limits.h>
 #include <java-cpool.h>
 #include <execution.h>
+#ifdef INTERPRETER
 #include <jvmti.h>
 #include "jvmti-int.h"
+#endif
 #include <java/lang/Class.h>
 #include <java/lang/String.h>
 #include <java/lang/StringBuffer.h>
@@ -243,13 +246,9 @@ _Jv_Linker::find_field (jclass klass, jclass owner,
   if (_Jv_CheckAccess (klass, *found_class, the_field->flags))
     {
       // Note that the field returned by find_field_helper is always
-      // resolved.  There's no point checking class loaders here,
-      // since we already did the work to look up all the types.
-      // FIXME: being lazy here would be nice.
-      if (the_field->type != field_type)
-       throw new java::lang::LinkageError
-         (JvNewStringLatin1 
-          ("field type mismatch with different loaders"));
+      // resolved.  However, we still use the constraint mechanism
+      // because this may affect other lookups.
+      _Jv_CheckOrCreateLoadingConstraint (klass, (*found_class)->loader);
     }
   else
     {
@@ -266,6 +265,23 @@ _Jv_Linker::find_field (jclass klass, jclass owner,
   return the_field;
 }
 
+// Check loading constraints for method.
+void
+_Jv_Linker::check_loading_constraints (_Jv_Method *method, jclass self_class,
+                                      jclass other_class)
+{
+  JArray<jclass> *klass_args;
+  jclass klass_return;
+
+  _Jv_GetTypesFromSignature (method, self_class, &klass_args, &klass_return);
+  jclass *klass_arg = elements (klass_args);
+  java::lang::ClassLoader *found_loader = other_class->loader;
+
+  _Jv_CheckOrCreateLoadingConstraint (klass_return, found_loader);
+  for (int i = 0; i < klass_args->length; i++)
+    _Jv_CheckOrCreateLoadingConstraint (*(klass_arg++), found_loader);
+}
+
 _Jv_Method *
 _Jv_Linker::resolve_method_entry (jclass klass, jclass &found_class,
                                  int class_index, int name_and_type_index,
@@ -356,39 +372,10 @@ _Jv_Linker::resolve_method_entry (jclass klass, jclass &found_class,
       throw new java::lang::NoSuchMethodError (sb->toString());
     }
 
-  // if (found_class->loader != klass->loader), then we
-  // must actually check that the types of arguments
-  // correspond.  That is, for each argument type, and
-  // the return type, doing _Jv_FindClassFromSignature
-  // with either loader should produce the same result,
-  // i.e., exactly the same jclass object. JVMS 5.4.3.3
+  // if (found_class->loader != klass->loader), then we must actually
+  // check that the types of arguments correspond.  JVMS 5.4.3.3.
   if (found_class->loader != klass->loader)
-    {
-      JArray<jclass> *found_args, *klass_args;
-      jclass found_return, klass_return;
-
-      _Jv_GetTypesFromSignature (the_method,
-                                found_class,
-                                &found_args,
-                                &found_return);
-      _Jv_GetTypesFromSignature (the_method,
-                                klass,
-                                &klass_args,
-                                &klass_return);
-
-      jclass *found_arg = elements (found_args);
-      jclass *klass_arg = elements (klass_args);
-
-      for (int i = 0; i < found_args->length; i++)
-       {
-         if (*(found_arg++) != *(klass_arg++))
-           throw new java::lang::LinkageError (JvNewStringLatin1 
-             ("argument type mismatch with different loaders"));
-       }
-      if (found_return != klass_return)
-       throw new java::lang::LinkageError (JvNewStringLatin1
-         ("return type mismatch with different loaders"));
-    }
+    check_loading_constraints (the_method, klass, found_class);
   
   return the_method;
 }
@@ -660,10 +647,11 @@ _Jv_Linker::prepare_constant_time_tables (jclass klass)
   // interfaces or primitive types.
    
   jclass klass0 = klass;
-  jboolean has_interfaces = 0;
+  jboolean has_interfaces = false;
   while (klass0 != &java::lang::Object::class$)
     {
-      has_interfaces += klass0->interface_count;
+      if (klass0->interface_count)
+       has_interfaces = true;
       klass0 = klass0->superclass;
       klass->depth++;
     }
@@ -853,7 +841,7 @@ _Jv_ThrowNoSuchMethodError ()
   throw new java::lang::NoSuchMethodError;
 }
 
-#if defined USE_LIBFFI && FFI_CLOSURES
+#if defined USE_LIBFFI && FFI_CLOSURES && defined(INTERPRETER)
 // A function whose invocation is prepared using libffi. It gets called
 // whenever a static method of a missing class is invoked. The data argument
 // holds a reference to a String denoting the missing class.
@@ -921,7 +909,8 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
        continue;
 
       meth = NULL;
-      for (jclass cl = klass; cl; cl = cl->getSuperclass())
+      jclass cl;
+      for (cl = klass; cl; cl = cl->getSuperclass())
         {
          meth = _Jv_GetMethodLocal (cl, iface->methods[j].name,
                                     iface->methods[j].signature);
@@ -943,6 +932,9 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
            itable[pos] = (void *) &_Jv_ThrowAbstractMethodError;
          else
            itable[pos] = meth->ncode;
+
+         if (cl->loader != iface->loader)
+           check_loading_constraints (meth, cl, iface);
        }
       else
         {
@@ -1039,7 +1031,7 @@ _Jv_Linker::find_iindex (jclass *ifaces, jshort *offsets, jshort num)
   return i;
 }
 
-#if defined USE_LIBFFI && FFI_CLOSURES
+#if defined USE_LIBFFI && FFI_CLOSURES && defined(INTERPRETER)
 // We use a structure of this type to store the closure that
 // represents a missing method.
 struct method_closure
@@ -1497,6 +1489,11 @@ _Jv_Linker::layout_vtable_methods (jclass klass)
                  sb->append(_Jv_GetMethodString(declarer, super_meth));
                  throw new VerifyError(sb->toString());
                }
+             else if (declarer->loader != klass->loader)
+               {
+                 // JVMS 5.4.2.
+                 check_loading_constraints (meth, klass, declarer);
+               }
            }
        }
 
@@ -2069,6 +2066,7 @@ _Jv_Linker::wait_for_state (jclass klass, int state)
       throw new java::lang::LinkageError;
   }
 
+#ifdef INTERPRETER
   if (__builtin_expect (klass->state == JV_STATE_LINKED, false)
       && state >= JV_STATE_LINKED
       && JVMTI_REQUESTED_EVENT (ClassPrepare))
@@ -2077,4 +2075,5 @@ _Jv_Linker::wait_for_state (jclass klass, int state)
       _Jv_JVMTI_PostEvent (JVMTI_EVENT_CLASS_PREPARE, self, jni_env,
                           klass);
     }
+#endif
 }