PR libgcj/25265 second part: Throw NoSuchFieldError for missing fields

Andrew Haley aph@redhat.com
Wed Dec 7 18:07:00 GMT 2005


This is the second part of the patch, the part that defers throwing a
NoSuchFieldError until we try to use a missing field.

Unfortunately, this really requires us to insert some
compiler-generated code.  On the plus side, this is only necessary
when accessing fields that beling to some other class, and in
Object-Oriented programming we really aren't supposed to do that sort
of thing.  So it doesn't matter.  ;-)

Andrew.

Index: gcc/java/decl.c
===================================================================
*** gcc/java/decl.c	(revision 107713)
--- gcc/java/decl.c	(working copy)
***************
*** 1117,1120 ****
--- 1117,1129 ----
    TREE_SIDE_EFFECTS (soft_abstractmethod_node) = 1;
  
+   soft_nosuchfield_node
+     = builtin_function ("_Jv_ThrowNoSuchFieldError",
+ 			build_function_type (void_type_node, endlink),
+ 			0, NOT_BUILT_IN, NULL, NULL_TREE);
+   /* Mark soft_nosuchfield_node as a `noreturn' function with side
+      effects.  */
+   TREE_THIS_VOLATILE (soft_nosuchfield_node) = 1;
+   TREE_SIDE_EFFECTS (soft_nosuchfield_node) = 1;
+ 
    t = tree_cons (NULL_TREE, class_ptr_type,
  		 tree_cons (NULL_TREE, object_ptr_type_node, endlink));
Index: gcc/java/expr.c
===================================================================
*** gcc/java/expr.c	(revision 107713)
--- gcc/java/expr.c	(working copy)
***************
*** 1704,1707 ****
--- 1704,1718 ----
  	  tree address;
  
+ 	  if (DECL_CONTEXT (field_decl) != output_class)
+ 	    field_offset
+ 	      = build3 (COND_EXPR, TREE_TYPE (field_offset),
+ 			build2 (EQ_EXPR, boolean_type_node,
+ 				field_offset, integer_zero_node),
+ 			build3 (CALL_EXPR, void_type_node, 
+ 				build_address_of (soft_nosuchfield_node),
+ 				build_tree_list (NULL_TREE, otable_index), 
+ 				NULL_TREE),
+ 			field_offset);
+ 	  
  	  field_offset = fold (convert (sizetype, field_offset));
  	  address 
Index: gcc/java/java-tree.h
===================================================================
*** gcc/java/java-tree.h	(revision 107713)
--- gcc/java/java-tree.h	(working copy)
***************
*** 387,390 ****
--- 387,391 ----
    JTI_SOFT_NULLPOINTER_NODE,
    JTI_SOFT_ABSTRACTMETHOD_NODE,
+   JTI_SOFT_NOSUCHFIELD_NODE,
    JTI_SOFT_CHECKARRAYSTORE_NODE,
    JTI_SOFT_MONITORENTER_NODE,
***************
*** 649,652 ****
--- 650,655 ----
  #define soft_abstractmethod_node \
    java_global_trees[JTI_SOFT_ABSTRACTMETHOD_NODE]
+ #define soft_nosuchfield_node \
+   java_global_trees[JTI_SOFT_NOSUCHFIELD_NODE]
  #define soft_checkarraystore_node \
    java_global_trees[JTI_SOFT_CHECKARRAYSTORE_NODE]
Index: libjava/link.cc
===================================================================
*** libjava/link.cc	(revision 107894)
--- libjava/link.cc	(working copy)
***************
*** 714,717 ****
--- 714,728 ----
  }
  
+ // Throw a NoSuchFieldError.  Called by compiler-generated code when
+ // an otable entry is zero.  OTABLE_INDEX is the index in the caller's
+ // otable that refers to the missing field.  This index may be used to
+ // print diagnostic information about the field.
+ void
+ _Jv_ThrowNoSuchFieldError (int /* otable_index */)
+ {
+   throw new java::lang::NoSuchFieldError;
+ }
+ 
+ 
  // This is put in empty vtable slots.
  void
***************
*** 972,981 ****
  	wait_for_state(target_class, JV_STATE_PREPARED);
  	jclass found_class;
! 	_Jv_Field *the_field = find_field (klass, target_class, &found_class,
! 					   sym.name, sym.signature);
! 	if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
! 	  throw new java::lang::IncompatibleClassChangeError;
! 	else
! 	  klass->otable->offsets[index] = the_field->u.boffset;
        }
      }
--- 1004,1021 ----
  	wait_for_state(target_class, JV_STATE_PREPARED);
  	jclass found_class;
! 	_Jv_Field *the_field = NULL;
! 	try
! 	  {
! 	    the_field = find_field (klass, target_class, &found_class,
! 				    sym.name, sym.signature);
! 	    if ((the_field->flags & java::lang::reflect::Modifier::STATIC))
! 	      throw new java::lang::IncompatibleClassChangeError;
! 	    else
! 	      klass->otable->offsets[index] = the_field->u.boffset;
! 	  }
! 	catch (java::lang::NoSuchFieldError *err)
! 	  {
! 	    klass->otable->offsets[index] = 0;
! 	  }
        }
      }
Index: libjava/include/jvm.h
===================================================================
*** libjava/include/jvm.h	(revision 107894)
--- libjava/include/jvm.h	(working copy)
***************
*** 443,446 ****
--- 443,450 ----
  extern "C" void _Jv_ThrowNullPointerException (void)
    __attribute__((noreturn));
+ extern "C" void _Jv_ThrowNoSuchMethodError (void)
+   __attribute__((noreturn));
+ extern "C" void _Jv_ThrowNoSuchFieldError (int)
+   __attribute__((noreturn));
  extern "C" jobject _Jv_NewArray (jint type, jint size)
    __attribute__((__malloc__));



More information about the Java-patches mailing list