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