re PR libgcj/21906 (hang when invoking abstract method)
authorTom Tromey <tromey@redhat.com>
Wed, 15 Jun 2005 19:11:43 +0000 (19:11 +0000)
committerTom Tromey <tromey@gcc.gnu.org>
Wed, 15 Jun 2005 19:11:43 +0000 (19:11 +0000)
gcc/java/:
PR libgcj/21906:
* class.c (make_method_value): Use soft_abstractmethod_node for
abstract method.
* java-tree.h (soft_abstractmethod_node): New define.
(JTI_SOFT_ABSTRACTMETHOD_NODE): New enum constant.
* decl.c (java_init_decl_processing): Initialize
soft_abstractmethod_node.
libjava/:
PR libgcj/21906:
* defineclass.cc (handleMethodsEnd): Set ncode for abstract
methods.
* include/jvm.h (_Jv_ThrowAbstractMethodError): Declare.
* link.cc (_Jv_ThrowAbstractMethodError): Renamed.  No longer
static.
(append_partial_itable): Use it.
(set_vtable_entries): Likewise.

From-SVN: r100992

gcc/java/ChangeLog
gcc/java/class.c
gcc/java/decl.c
gcc/java/java-tree.h
libjava/ChangeLog
libjava/defineclass.cc
libjava/include/jvm.h
libjava/link.cc

index d8cdd41..b6f6e3a 100644 (file)
@@ -1,3 +1,13 @@
+2005-06-15  Tom Tromey  <tromey@redhat.com>
+
+       PR libgcj/21906:
+       * class.c (make_method_value): Use soft_abstractmethod_node for
+       abstract method.
+       * java-tree.h (soft_abstractmethod_node): New define.
+       (JTI_SOFT_ABSTRACTMETHOD_NODE): New enum constant.
+       * decl.c (java_init_decl_processing): Initialize
+       soft_abstractmethod_node.
+
 2005-06-13  Geoffrey Keating  <geoffk@apple.com>
 
        * Make-lang.in (rule for installing gcj.1): Depends on installdirs.
index a555bf0..f444121 100644 (file)
@@ -1315,7 +1315,10 @@ make_method_value (tree mdecl)
     index = integer_minus_one_node;
 
   code = null_pointer_node;
-  if (!METHOD_ABSTRACT (mdecl))
+  if (METHOD_ABSTRACT (mdecl))
+    code = build1 (ADDR_EXPR, nativecode_ptr_type_node,
+                  soft_abstractmethod_node);
+  else
     code = build1 (ADDR_EXPR, nativecode_ptr_type_node, 
                   make_local_function_alias (mdecl));
   START_RECORD_CONSTRUCTOR (minit, method_type_node);
index 891e4db..5240fba 100644 (file)
@@ -1107,6 +1107,15 @@ java_init_decl_processing (void)
   TREE_THIS_VOLATILE (soft_nullpointer_node) = 1;
   TREE_SIDE_EFFECTS (soft_nullpointer_node) = 1;
 
+  soft_abstractmethod_node
+    = builtin_function ("_Jv_ThrowAbstractMethodError",
+                       build_function_type (void_type_node, endlink),
+                       0, NOT_BUILT_IN, NULL, NULL_TREE);
+  /* Mark soft_abstractmethod_node as a `noreturn' function with side
+     effects.  */
+  TREE_THIS_VOLATILE (soft_abstractmethod_node) = 1;
+  TREE_SIDE_EFFECTS (soft_abstractmethod_node) = 1;
+
   t = tree_cons (NULL_TREE, class_ptr_type,
                 tree_cons (NULL_TREE, object_ptr_type_node, endlink));
   soft_checkcast_node
index 5651dc3..3d0f233 100644 (file)
@@ -392,6 +392,7 @@ enum java_tree_index
   JTI_SOFT_MULTIANEWARRAY_NODE,
   JTI_SOFT_BADARRAYINDEX_NODE,
   JTI_SOFT_NULLPOINTER_NODE,
+  JTI_SOFT_ABSTRACTMETHOD_NODE,
   JTI_SOFT_CHECKARRAYSTORE_NODE,
   JTI_SOFT_MONITORENTER_NODE,
   JTI_SOFT_MONITOREXIT_NODE,
@@ -651,6 +652,8 @@ extern GTY(()) tree java_global_trees[JTI_MAX];
   java_global_trees[JTI_SOFT_BADARRAYINDEX_NODE]
 #define soft_nullpointer_node \
   java_global_trees[JTI_SOFT_NULLPOINTER_NODE]
+#define soft_abstractmethod_node \
+  java_global_trees[JTI_SOFT_ABSTRACTMETHOD_NODE]
 #define soft_checkarraystore_node \
   java_global_trees[JTI_SOFT_CHECKARRAYSTORE_NODE]
 #define soft_monitorenter_node \
index b832616..813eef1 100644 (file)
@@ -1,5 +1,16 @@
 2005-06-15  Tom Tromey  <tromey@redhat.com>
 
+       PR libgcj/21906:
+       * defineclass.cc (handleMethodsEnd): Set ncode for abstract
+       methods.
+       * include/jvm.h (_Jv_ThrowAbstractMethodError): Declare.
+       * link.cc (_Jv_ThrowAbstractMethodError): Renamed.  No longer
+       static.
+       (append_partial_itable): Use it.
+       (set_vtable_entries): Likewise.
+
+2005-06-15  Tom Tromey  <tromey@redhat.com>
+
        * gnu/gcj/runtime/SystemClassLoader.java (init): Clear
        last_was_sep in loop.
 
index 111b1fb..7564957 100644 (file)
@@ -1288,7 +1288,7 @@ void _Jv_ClassReader::handleMethod
        throw_class_format_error ("erroneous method access flags");
 
       // FIXME: JVM spec S4.6: if ABSTRACT modifier is set, verify other 
-      // flags are not set. Verify flags for interface methods. Verifiy
+      // flags are not set. Verify flags for interface methods.  Verify
       // modifiers for initializers. 
     }
 }
@@ -1378,6 +1378,7 @@ void _Jv_ClassReader::handleMethodsEnd ()
        {
          if (def_interp->interpreted_methods[i] != 0)
            throw_class_format_error ("code provided for abstract method");
+         method->ncode = (void *) &_Jv_ThrowAbstractMethodError;
        }
       else
        {
index 3a2eb9b..606a84d 100644 (file)
@@ -482,6 +482,8 @@ extern void _Jv_CallAnyMethodA (jobject obj,
 extern jobject _Jv_NewMultiArray (jclass, jint ndims, jint* dims)
   __attribute__((__malloc__));
 
+extern "C" void _Jv_ThrowAbstractMethodError () __attribute__((__noreturn__));
+
 /* Checked divide subroutines. */
 extern "C"
 {
index 3fe0734..e97b31b 100644 (file)
@@ -714,8 +714,8 @@ _Jv_ThrowNoSuchMethodError ()
 }
 
 // This is put in empty vtable slots.
-static void
-_Jv_abstractMethodError (void)
+void
+_Jv_ThrowAbstractMethodError ()
 {
   throw new java::lang::AbstractMethodError();
 }
@@ -767,7 +767,7 @@ _Jv_Linker::append_partial_itable (jclass klass, jclass iface,
              (_Jv_GetMethodString (klass, meth));
 
          if ((meth->accflags & Modifier::ABSTRACT) != 0)
-           itable[pos] = (void *) &_Jv_abstractMethodError;
+           itable[pos] = (void *) &_Jv_ThrowAbstractMethodError;
          else
            itable[pos] = meth->ncode;
        }
@@ -1228,7 +1228,8 @@ _Jv_Linker::set_vtable_entries (jclass klass, _Jv_VTable *vtable)
       if ((meth->accflags & Modifier::ABSTRACT))
        // FIXME: it might be nice to have a libffi trampoline here,
        // so we could pass in the method name and other information.
-       vtable->set_method(meth->index, (void *) &_Jv_abstractMethodError);
+       vtable->set_method(meth->index,
+                          (void *) &_Jv_ThrowAbstractMethodError);
       else
        vtable->set_method(meth->index, meth->ncode);
     }