OSDN Git Service

2001-03-23 Bryce McKinlay <bryce@albatross.co.nz>
authorbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Mar 2001 01:49:11 +0000 (01:49 +0000)
committerbryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>
Fri, 23 Mar 2001 01:49:11 +0000 (01:49 +0000)
* extend.texi: Document the "java_interface" attribute.

java/:
2001-03-21  Bryce McKinlay  <bryce@albatross.co.nz>

* gjavah.c (process_file): Mark interface definitions with
"__attribute__ ((java_interface))".

cp/:
2001-03-22  Bryce McKinlay  <bryce@albatross.co.nz>

Add support for Java interface method calls.
* cp-tree.h (struct lang_type): Add java_interface flag.
(TYPE_JAVA_INTERFACE): New macro.
* tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
by setting TYPE_JAVA_INTERFACE.
* call.c (java_iface_lookup_fn): New static.
(build_over_call): If calling a method declared in a
TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
expression which resolves the function address.
(build_java_interface_fn_ref): New function.

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

gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/call.c
gcc/cp/cp-tree.h
gcc/cp/tree.c
gcc/extend.texi
gcc/java/ChangeLog
gcc/java/gjavah.c

index 07dcc2f..e733bfd 100644 (file)
@@ -1,3 +1,7 @@
+2001-03-23  Bryce McKinlay  <bryce@albatross.co.nz>
+
+       * extend.texi: Document the "java_interface" attribute.
+
 2001-03-22  Zack Weinberg  <zackw@stanford.edu>
 
        * mkconfig.sh: Use a subshell with redirected stdout,
index 7eb92b2..e85d6b8 100644 (file)
@@ -1,3 +1,16 @@
+2001-03-22  Bryce McKinlay  <bryce@albatross.co.nz>
+
+       Add support for Java interface method calls.
+       * cp-tree.h (struct lang_type): Add java_interface flag.
+       (TYPE_JAVA_INTERFACE): New macro.
+       * tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
+       by setting TYPE_JAVA_INTERFACE.
+       * call.c (java_iface_lookup_fn): New static.
+       (build_over_call): If calling a method declared in a 
+       TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
+       expression which resolves the function address.
+       (build_java_interface_fn_ref): New function.
+
 2001-03-22  Richard Henderson  <rth@redhat.com>
 
        * Make-lang.in (cp/except.o): Don't depend on insn-flags.h.
index 13827c9..0850f9b 100644 (file)
@@ -45,6 +45,7 @@ static int equal_functions PARAMS ((tree, tree));
 static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
 static int compare_ics PARAMS ((tree, tree));
 static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
+static tree build_java_interface_fn_ref PARAMS ((tree, tree));
 #define convert_like(CONV, EXPR) convert_like_real (CONV, EXPR, NULL_TREE, 0, 0)
 #define convert_like_with_context(CONV, EXPR, FN, ARGNO) convert_like_real (CONV, EXPR, FN, ARGNO, 0)
 static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
@@ -4271,7 +4272,10 @@ build_over_call (cand, args, flags)
       if (TREE_SIDE_EFFECTS (*p))
        *p = save_expr (*p);
       t = build_pointer_type (TREE_TYPE (fn));
-      fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
+      if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
+       fn = build_java_interface_fn_ref (fn, *p);
+      else
+       fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
       TREE_TYPE (fn) = t;
     }
   else if (DECL_INLINE (fn))
@@ -4306,6 +4310,72 @@ build_over_call (cand, args, flags)
   return convert_from_reference (fn);
 }
 
+static tree java_iface_lookup_fn;
+
+/* Make an expression which yields the address of the Java interface
+   method FN.  This is achieved by generating a call to libjava's
+   _Jv_LookupInterfaceMethodIdx().  */
+
+static tree
+build_java_interface_fn_ref (fn, instance)
+    tree fn, instance;
+{
+  tree lookup_args, lookup_fn, method, idx;
+  tree klass_ref, iface, iface_ref;
+  int i;
+  
+  if (!java_iface_lookup_fn)
+    {
+      tree endlink = build_void_list_node ();
+      tree t = tree_cons (NULL_TREE, ptr_type_node,
+                         tree_cons (NULL_TREE, ptr_type_node,
+                                    tree_cons (NULL_TREE, java_int_type_node,
+                                               endlink)));
+      java_iface_lookup_fn 
+       = builtin_function ("_Jv_LookupInterfaceMethodIdx",
+                           build_function_type (ptr_type_node, t),
+                           0, NOT_BUILT_IN, NULL_PTR);
+      ggc_add_tree_root (&java_iface_lookup_fn, 1);
+    }
+
+  /* Look up the pointer to the runtime java.lang.Class object for `instance'. 
+     This is the first entry in the vtable. */
+  klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0), 
+                             integer_zero_node);
+
+  /* Get the java.lang.Class pointer for the interface being called. */
+  iface = DECL_CONTEXT (fn);
+  iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0);
+  if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL
+      || DECL_CONTEXT (iface_ref) != iface)
+    {
+      cp_error ("Could not find class$ field in java interface type `%T'", 
+               iface);
+      return error_mark_node;
+    }
+  iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref);
+  
+  /* Determine the itable index of FN. */
+  i = 1;
+  for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method))
+    {
+      if (!DECL_VIRTUAL_P (method))
+        continue;
+      if (fn == method)
+        break;
+      i++;
+    }
+  idx = build_int_2 (i, 0);
+
+  lookup_args = tree_cons (NULL_TREE, klass_ref, 
+                          tree_cons (NULL_TREE, iface_ref,
+                                     build_tree_list (NULL_TREE, idx)));
+  lookup_fn = build1 (ADDR_EXPR, 
+                     build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
+                     java_iface_lookup_fn);
+  return build (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args, NULL_TREE);
+}
+
 /* Returns the value to use for the in-charge parameter when making a
    call to a function with the indicated NAME.  */
 
index de63fb1..f8dd692 100644 (file)
@@ -1326,6 +1326,7 @@ struct lang_type
   unsigned has_abstract_assign_ref : 1;
   unsigned non_aggregate : 1;
   unsigned is_partial_instantiation : 1;
+  unsigned java_interface : 1;
 
   /* When adding a flag here, consider whether or not it ought to
      apply to a template instance if it applies to the template.  If
@@ -1334,7 +1335,7 @@ struct lang_type
   /* There are some bits left to fill out a 32-bit word.  Keep track
      of this by updating the size of this bitfield whenever you add or
      remove a flag.  */
-  unsigned dummy : 9;
+  unsigned dummy : 8;
 
   int vsize;
 
@@ -1556,6 +1557,10 @@ struct lang_type
 #define CLASSTYPE_ALIGN_UNIT(NODE) \
   (CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT)
 
+/* True if this a Java interface type, declared with 
+   '__attribute__ ((java_interface))'. */
+#define TYPE_JAVA_INTERFACE(NODE) (TYPE_LANG_SPECIFIC(NODE)->java_interface)
+
 /* A cons list of virtual functions which cannot be inherited by
    derived classes.  When deriving from this type, the derived
    class must provide its own definition for each of these functions.  */
index 93e12be..3023e8f 100644 (file)
@@ -2212,6 +2212,19 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
   tree decl ATTRIBUTE_UNUSED;
   tree type ATTRIBUTE_UNUSED;
 {
+  if (is_attribute_p ("java_interface", attr_name))
+    {
+      if (attr_args != NULL_TREE
+         || decl != NULL_TREE
+         || ! CLASS_TYPE_P (type)
+         || ! TYPE_FOR_JAVA (type))
+       {
+         error ("`java_interface' attribute can only be applied to Java class definitions");
+         return 0;
+       }
+      TYPE_JAVA_INTERFACE (type) = 1;
+      return 1;
+    }
   if (is_attribute_p ("com_interface", attr_name))
     {
       if (! flag_vtable_thunks)
index 3319cca..49fe319 100644 (file)
@@ -4355,6 +4355,14 @@ changed to be COM-compliant.  Also, all classes and structs derived from one
 marked with this attribute are implicitly marked with the same attribute;
 thus, only the base class in a COM hierarchy needs @code{com_interface}.
 
+@item java_interface
+@cindex java_interface attribute
+
+This type attribute informs C++ that the class is a Java interface.  It may 
+only be applied to classes declared within an @code{extern "Java"} block.
+Calls to methods declared in this interface will be dispatched using GCJ's 
+interface table mechanism, instead of regular virtual table dispatch.  
+
 @end table
 
 @node Deprecated Features
index 6a23f8e..d7d0e77 100644 (file)
@@ -1,3 +1,8 @@
+2001-03-21  Bryce McKinlay  <bryce@albatross.co.nz>
+
+       * gjavah.c (process_file): Mark interface definitions with 
+       "__attribute__ ((java_interface))".
+
 2001-03-21  Alexandre Petit-Bianco  <apbianco@redhat.com>
 
        * class.c (layout_class): Fixed push_super_field's second
index 809ccf4..7f60849 100644 (file)
@@ -1857,7 +1857,12 @@ DEFUN(process_file, (jcf, out),
          generate_access (out, ACC_PUBLIC);
          fprintf (out, "\n  static ::java::lang::Class class$;\n");
 
-         fputs ("};\n", out);
+         fputs ("}", out);
+         
+         if (jcf->access_flags & ACC_INTERFACE)
+           fputs (" __attribute__ ((java_interface))", out);
+
+         fputs (";\n", out);
 
          if (append_count > 0)
            fputc ('\n', out);