[multiple changes]
authorBryce McKinlay <bryce@gcc.gnu.org>
Wed, 14 Apr 2004 17:45:20 +0000 (18:45 +0100)
committerBryce McKinlay <bryce@gcc.gnu.org>
Wed, 14 Apr 2004 17:45:20 +0000 (18:45 +0100)
2004-04-14  Andrew Haley  <aph@redhat.com>
            Bryce McKinlay  <mckinlay@redhat.com>

* java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
_Jv_LookupInterfaceMethodIdx for calls to interfaces.
* include/jvm.h (_Jv_CallAnyMethodA): Add new  face' arg.

* testsuite/libjava.lang/InvokeInterface.java: New file.
* testsuite/libjava.lang/InvokeInterface.out: New file.

2004-04-14  Bryce McKinlay  <mckinlay@redhat.com>

* class.c (get_interface_method_index): New function. Return
dispatch index for interface method.
(make_method_value): For interface methods, set index field to
iface dispatch index, not DECL_VINDEX.
* expr.c (build_invokeinterface): Use get_interface_method_index.

From-SVN: r80684

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/expr.c
gcc/java/java-tree.h
libjava/ChangeLog
libjava/include/jvm.h
libjava/java/lang/reflect/natMethod.cc
libjava/testsuite/Makefile.in
libjava/testsuite/libjava.lang/InvokeInterface.java [new file with mode: 0644]
libjava/testsuite/libjava.lang/InvokeInterface.out [new file with mode: 0644]

index b63afb3592380146f14ed9ece3eaac4f877d5233..3af84d00cb148598cac7308d939e112fffcd2c07 100644 (file)
@@ -1,3 +1,11 @@
+2004-04-12  Bryce McKinlay  <mckinlay@redhat.com>
+
+       * class.c (get_interface_method_index): New function. Return dispatch 
+       index for interface method.
+       (make_method_value): For interface methods, set index field to
+       iface dispatch index, not DECL_VINDEX.
+       * expr.c (build_invokeinterface): Use get_interface_method_index.
+
 2004-03-31  Richard Kenner  <kenner@vlsi1.ultra.nyu.edu>
 
        * jcf-write.c (generate_bytecode_insns): Use TYPE_UNSIGNED.
index 66bdeb934fd834d8ab1a1641957cf92157345cfb..3ba60bd509ee709cf65a25d60b205232fb3068df 100644 (file)
@@ -1246,10 +1246,15 @@ make_method_value (tree mdecl)
   tree minit;
   tree index;
   tree code;
+  tree class_decl;
 #define ACC_TRANSLATED          0x4000
   int accflags = get_access_flags_from_decl (mdecl) | ACC_TRANSLATED;
-
-  if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
+  
+  class_decl = DECL_CONTEXT (mdecl);
+  /* For interfaces, the index field contains the dispatch index. */
+  if (CLASS_INTERFACE (TYPE_NAME (class_decl)))
+    index = build_int_2 (get_interface_method_index (mdecl, class_decl), 0);
+  else if (!flag_indirect_dispatch && DECL_VINDEX (mdecl) != NULL_TREE)
     index = DECL_VINDEX (mdecl);
   else
     index = integer_minus_one_node;
@@ -2133,6 +2138,23 @@ layout_class_methods (tree this_class)
   TYPE_NVIRTUALS (this_class) = dtable_count;
 }
 
+/* Return the index of METHOD in INTERFACE.  This index begins at 1 and is used as an
+   argument for _Jv_LookupInterfaceMethodIdx(). */
+int
+get_interface_method_index (tree method, tree interface)
+{
+  tree meth;
+  int i = 1;
+
+  for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
+    {
+      if (meth == method)
+       return i;
+      if (meth == NULL_TREE)
+       abort ();
+    }
+}
+
 /* Lay METHOD_DECL out, returning a possibly new value of
    DTABLE_COUNT. Also mangle the method's name. */
 
index 95c3b69d7d9b7e5d8b8d2ea267f9059c433619e4..79a3f4ddd2c7b13fdc94f39c3a729deaa1073f06 100644 (file)
@@ -1974,17 +1974,7 @@ build_invokeinterface (tree dtable, tree method)
     }
   else
     {
-      i = 1;
-      for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
-       {
-         if (meth == method)
-            {
-             idx = build_int_2 (i, 0);
-             break;
-           }
-         if (meth == NULL_TREE)
-           abort ();
-       }
+      idx = build_int_2 (get_interface_method_index (method, interface), 0);
     }
 
   lookup_arg = tree_cons (NULL_TREE, dtable,
index 169f0ad4007213fd23c07b497b2c39c1de91f3b6..8a9f9a9b887ad472dd57bd9846e15777f230bdad 100644 (file)
@@ -1149,6 +1149,7 @@ extern tree unmangle_classname (const char *name, int name_length);
 extern tree parse_signature_string (const unsigned char *, int);
 extern tree get_type_from_signature (tree);
 extern void layout_class (tree);
+extern int get_interface_method_index (tree, tree);
 extern tree layout_class_method (tree, tree, tree, tree);
 extern void layout_class_methods (tree);
 extern tree build_class_ref (tree);
index 787119bde05cea8d6439707ac29e2f7a5d3fdc49..297bd7066cbcfb30cb43146533deedaceb18da9e 100644 (file)
@@ -1,3 +1,13 @@
+2004-04-14  Andrew Haley  <aph@redhat.com>
+            Bryce McKinlay  <mckinlay@redhat.com>
+
+       * java/lang/reflect/natMethod.cc (_Jv_CallAnyMethodA): Use
+       _Jv_LookupInterfaceMethodIdx for calls to interfaces.
+       * include/jvm.h (_Jv_CallAnyMethodA): Add new `iface' arg.
+
+       * testsuite/libjava.lang/InvokeInterface.java: New file.
+       * testsuite/libjava.lang/InvokeInterface.out: New file.
+
 2004-04-09  Ranjit Mathew  <rmathew@hotmail.com>
        
        * java/lang/VMThrowable.java (getStackTrace): Pass trace as-is to
index ee7792b07887ab319e78a74536f3435c8a65a2c5..398f854e7836186c7ea0053391367e2b59ddb693 100644 (file)
@@ -422,7 +422,8 @@ extern jboolean _Jv_CheckAccess (jclass self_klass, jclass other_klass,
 extern jobject _Jv_CallAnyMethodA (jobject obj, jclass return_type,
                                   jmethodID meth, jboolean is_constructor,
                                   JArray<jclass> *parameter_types,
-                                  jobjectArray args);
+                                  jobjectArray args,
+                                  jclass iface = NULL);
 
 union jvalue;
 extern void _Jv_CallAnyMethodA (jobject obj,
@@ -433,7 +434,8 @@ extern void _Jv_CallAnyMethodA (jobject obj,
                                JArray<jclass> *parameter_types,
                                jvalue *args,
                                jvalue *result,
-                               jboolean is_jni_call = true);
+                               jboolean is_jni_call = true,
+                               jclass iface = NULL);
 
 extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
   __attribute__((__malloc__));
index 736103b63dd5987527407bd73dd1b6f6497b7fd4..96d293bf2410e881c121bfb7f5d81f41652ce068 100644 (file)
@@ -143,14 +143,14 @@ jobject
 java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
 {
   using namespace java::lang::reflect;
+  jclass iface = NULL;
   
   if (parameter_types == NULL)
     getType ();
     
   jmethodID meth = _Jv_FromReflectedMethod (this);
-
   jclass objClass;
-  
+
   if (Modifier::isStatic(meth->accflags))
     {
       // We have to initialize a static class.  It is safe to do this
@@ -188,8 +188,11 @@ java::lang::reflect::Method::invoke (jobject obj, jobjectArray args)
        throw new IllegalAccessException;
     }
 
+  if (declaringClass->isInterface())
+    iface = declaringClass;
+  
   return _Jv_CallAnyMethodA (obj, return_type, meth, false,
-                            parameter_types, args);
+                            parameter_types, args, iface);
 }
 
 jint
@@ -341,7 +344,8 @@ _Jv_CallAnyMethodA (jobject obj,
                    JArray<jclass> *parameter_types,
                    jvalue *args,
                    jvalue *result,
-                   jboolean is_jni_call)
+                   jboolean is_jni_call,
+                   jclass iface)
 {
   using namespace java::lang::reflect;
   
@@ -478,7 +482,10 @@ _Jv_CallAnyMethodA (jobject obj,
       && (_Jv_ushort)-1 != meth->index)
     {
       _Jv_VTable *vtable = *(_Jv_VTable **) obj;
-      ncode = vtable->get_method (meth->index);
+      if (iface == NULL)
+       ncode = vtable->get_method (meth->index);
+      else
+       ncode = _Jv_LookupInterfaceMethodIdx (vtable->clas, iface, meth->index);
     }
   else
     {
@@ -553,7 +560,8 @@ _Jv_CallAnyMethodA (jobject obj,
                    jmethodID meth,
                    jboolean is_constructor,
                    JArray<jclass> *parameter_types,
-                   jobjectArray args)
+                   jobjectArray args,
+                   jclass iface)
 {
   if (parameter_types->length == 0 && args == NULL)
     {
@@ -621,7 +629,7 @@ _Jv_CallAnyMethodA (jobject obj,
   _Jv_CallAnyMethodA (obj, return_type, meth, is_constructor,
                      _Jv_isVirtualMethod (meth),
                      parameter_types, argvals, &ret_value,
-                     false);
+                     false, iface);
 
   jobject r;
 #define VAL(Wrapper, Field)  (new Wrapper (ret_value.Field))
index 129d25c647176dea660f78f416901565f0d15f9a..21c86dd9d018e0d76fa5f61e01910c463cc50314 100644 (file)
@@ -1,6 +1,6 @@
-# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
 
-# Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
 # This Makefile.in is free software; the Free Software Foundation
 # gives unlimited permission to copy and/or distribute it,
 # with or without modifications, as long as this notice is preserved.
diff --git a/libjava/testsuite/libjava.lang/InvokeInterface.java b/libjava/testsuite/libjava.lang/InvokeInterface.java
new file mode 100644 (file)
index 0000000..6f4dc61
--- /dev/null
@@ -0,0 +1,55 @@
+import java.lang.reflect.*;
+
+interface one
+{
+  int n(int N);
+}
+
+interface two
+{
+  int nn(int N);
+}
+
+interface three
+{
+  int nnn(int N);
+}
+
+class arse implements one, two
+{
+  public int n(int N) { return N; }
+  public int nn(int N) { return N*2; }
+}
+
+class arsey implements two, one, three
+{
+  public int n(int N) { return N*4; }
+  public int nn(int N) { return N*8; }
+  public int nnn(int N) { return N*16; }
+}
+
+public class InvokeInterface extends arse
+{
+  int f ()
+  {
+       return flunk.nn(1);
+  }
+  static two flunk = new arse();
+  static three flunkey = new arsey();
+  public static void main(String[] s) throws Throwable
+  {
+       Class[] argtypes = {Integer.TYPE};
+       Method m = two.class.getMethod("nn", argtypes);
+       Object[] args = {new Integer(1)};
+       System.out.println(flunk.nn(1));
+       System.out.println(m.invoke(new arse(), args));
+       m = arse.class.getMethod("nn", argtypes);
+       System.out.println(m.invoke(new arse(), args));
+       m = two.class.getMethod("nn", argtypes);
+       System.out.println(m.invoke(new arsey(), args));
+       m = three.class.getMethod("nnn", argtypes);
+       System.out.println(m.invoke(new arsey(), args));        
+       m = arsey.class.getMethod("nnn", argtypes);
+       System.out.println(m.invoke(new arsey(), args));        
+  }
+}
diff --git a/libjava/testsuite/libjava.lang/InvokeInterface.out b/libjava/testsuite/libjava.lang/InvokeInterface.out
new file mode 100644 (file)
index 0000000..803d026
--- /dev/null
@@ -0,0 +1,6 @@
+2
+2
+2
+8
+16
+16