aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/class.c
diff options
context:
space:
mode:
authorAndrew Haley <aph@redhat.com>2003-10-24 09:29:43 +0000
committerAndrew Haley <aph@gcc.gnu.org>2003-10-24 09:29:43 +0000
commit904715853c40f9a27b492794a6db817ea89a553a (patch)
tree8c726fb42c811bb6652ba1a759bae78c2c8d9378 /gcc/java/class.c
parentc769a35d59f282465c1a344617bf04d595e8c477 (diff)
downloadgcc-904715853c40f9a27b492794a6db817ea89a553a.zip
gcc-904715853c40f9a27b492794a6db817ea89a553a.tar.gz
gcc-904715853c40f9a27b492794a6db817ea89a553a.tar.bz2
lang.c (LANG_HOOKS_GET_CALLEE_FNDECL): New.
2003-10-22 Andrew Haley <aph@redhat.com> * lang.c (LANG_HOOKS_GET_CALLEE_FNDECL): New. (java_get_callee_fndecl): New. * jcf-parse.c (java_parse_file): Call emit_catch_table(). * java-tree.h (ctable_decl): New. (catch_classes): New. (java_tree_index): Add JTI_CTABLE_DECL, JTI_CATCH_CLASSES. * decl.c (java_init_decl_processing): Add catch_class_type. Add ctable_decl. Add catch_classes field. * class.c (build_indirect_class_ref): Break out from build_class_ref. (make_field_value): Check flag_indirect_dispatch. (make_class_data): Ditto. Tidy uses of PUSH_FIELD_VALUE. Add field catch_classes. (make_catch_class_record): New. * java-tree.h (PUSH_FIELD_VALUE): Tidy. 2003-10-22 Andrew Haley <aph@redhat.com> * java/lang/natClass.cc (initializeClass): Call _Jv_linkExceptionClassTable. (_Jv_LinkSymbolTable): Call )_Jv_ThrowNoSuchMethodError. Call _Jv_Defer_Resolution on a method whose ncode is NULL. (_Jv_linkExceptionClassTable): New function. (_Jv_LayoutVTableMethods): If superclass looks like a constant pool entry, look it up. * java/lang/Class.h (struct _Jv_CatchClass): New. (_Jv_linkExceptionClassTable): New friend. (_Jv_Defer_Resolution): New friend. (class Class.catch_classes): New field. * include/java-interp.h (Jv_Defer_Resolution): New method. (_Jv_PrepareClass): Make a friend of _Jv_MethodBase. (_Jv_MethodBase.deferred): New field. (_Jv_Defer_Resolution): New function. * resolve.cc (_Jv_PrepareClass): Resolve deferred handlers. * exception.cc (get_ttype_entry): Change return type to void**. (PERSONALITY_FUNCTION): Remove all code related to using a Utf8Const* for a match type. Change match type to be a pointer to a pointer, rather than a pointer to a Class. * defineclass.cc (handleCodeAttribute): Initialize method->deferred. (handleMethodsEnd): Likewise. From-SVN: r72886
Diffstat (limited to 'gcc/java/class.c')
-rw-r--r--gcc/java/class.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/gcc/java/class.c b/gcc/java/class.c
index 49e1a3d..2aacbd4 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -808,6 +808,20 @@ build_utf8_ref (tree name)
return ref;
}
+/* Like build_class_ref, but instead of a direct reference generate a
+ pointer into the constant pool. */
+
+static tree
+build_indirect_class_ref (tree type)
+{
+ int index;
+ tree cl;
+ index = alloc_class_constant (type);
+ cl = build_ref_from_constant_pool (index);
+ TREE_TYPE (cl) = promote_type (class_ptr_type);
+ return cl;
+}
+
/* Build a reference to the class TYPE.
Also handles primitive types and array types. */
@@ -820,6 +834,12 @@ build_class_ref (tree type)
tree ref, decl_name, decl;
if (TREE_CODE (type) == POINTER_TYPE)
type = TREE_TYPE (type);
+
+ if (flag_indirect_dispatch
+ && type != current_class
+ && TREE_CODE (type) == RECORD_TYPE)
+ return build_indirect_class_ref (type);
+
if (TREE_CODE (type) == RECORD_TYPE)
{
if (TYPE_SIZE (type) == error_mark_node)
@@ -902,14 +922,7 @@ build_class_ref (tree type)
return ref;
}
else
- {
- int index;
- tree cl;
- index = alloc_class_constant (type);
- cl = build_ref_from_constant_pool (index);
- TREE_TYPE (cl) = promote_type (class_ptr_type);
- return cl;
- }
+ return build_indirect_class_ref (type);
}
tree
@@ -1061,7 +1074,7 @@ make_field_value (tree fdecl)
tree finit;
int flags;
tree type = TREE_TYPE (fdecl);
- int resolved = is_compiled_class (type);
+ int resolved = is_compiled_class (type) && ! flag_indirect_dispatch;
START_RECORD_CONSTRUCTOR (finit, field_type_node);
PUSH_FIELD_VALUE (finit, "name", build_utf8_ref (DECL_NAME (fdecl)));
@@ -1422,7 +1435,8 @@ make_class_data (tree type)
super = CLASSTYPE_SUPER (type);
if (super == NULL_TREE)
super = null_pointer_node;
- else if (assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
+ else if (! flag_indirect_dispatch
+ && assume_compiled (IDENTIFIER_POINTER (DECL_NAME (type_decl)))
&& assume_compiled (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (super)))))
super = build_class_ref (super);
else
@@ -1492,7 +1506,7 @@ make_class_data (tree type)
PUSH_FIELD_VALUE (cons, "method_count", build_int_2 (method_count, 0));
if (flag_indirect_dispatch)
- PUSH_FIELD_VALUE (cons, "vtable_method_count", integer_minus_one_node)
+ PUSH_FIELD_VALUE (cons, "vtable_method_count", integer_minus_one_node);
else
PUSH_FIELD_VALUE (cons, "vtable_method_count", TYPE_NVIRTUALS (type));
@@ -1505,7 +1519,7 @@ make_class_data (tree type)
build_int_2 (static_field_count, 0));
if (flag_indirect_dispatch)
- PUSH_FIELD_VALUE (cons, "vtable", null_pointer_node)
+ PUSH_FIELD_VALUE (cons, "vtable", null_pointer_node);
else
PUSH_FIELD_VALUE (cons, "vtable",
dtable_decl == NULL_TREE ? null_pointer_node
@@ -1540,7 +1554,9 @@ make_class_data (tree type)
atable_syms_decl));
TREE_CONSTANT (atable_decl) = 1;
}
-
+
+ PUSH_FIELD_VALUE (cons, "catch_classes",
+ build1 (ADDR_EXPR, ptr_type_node, ctable_decl));
PUSH_FIELD_VALUE (cons, "interfaces", interfaces);
PUSH_FIELD_VALUE (cons, "loader", null_pointer_node);
PUSH_FIELD_VALUE (cons, "interface_count", build_int_2 (interface_len, 0));
@@ -2210,6 +2226,47 @@ emit_symbol_table (tree name, tree the_table, tree decl_list, tree the_syms_decl
return the_table;
}
+/* make an entry for the catch_classes list. */
+tree
+make_catch_class_record (tree catch_class, tree classname)
+{
+ tree entry;
+ tree type = TREE_TYPE (TREE_TYPE (ctable_decl));
+ START_RECORD_CONSTRUCTOR (entry, type);
+ PUSH_FIELD_VALUE (entry, "address", catch_class);
+ PUSH_FIELD_VALUE (entry, "classname", classname);
+ FINISH_RECORD_CONSTRUCTOR (entry);
+ return entry;
+}
+
+
+/* Generate the list of Throwable classes that are caught by exception
+ handlers in this compilation. */
+void
+emit_catch_table (void)
+{
+ tree table, table_size, array_type;
+ catch_classes
+ = tree_cons (NULL,
+ make_catch_class_record (null_pointer_node, null_pointer_node),
+ catch_classes);
+ catch_classes = nreverse (catch_classes);
+ catch_classes
+ = tree_cons (NULL,
+ make_catch_class_record (null_pointer_node, null_pointer_node),
+ catch_classes);
+ table_size = build_index_type (build_int_2 (list_length (catch_classes), 0));
+ array_type
+ = build_array_type (TREE_TYPE (TREE_TYPE (ctable_decl)), table_size);
+ table = build_decl (VAR_DECL, DECL_NAME (ctable_decl), array_type);
+ DECL_INITIAL (table) = build_constructor (array_type, catch_classes);
+ TREE_STATIC (table) = 1;
+ TREE_READONLY (table) = 1;
+ rest_of_decl_compilation (table, NULL, 1, 0);
+ ctable_decl = table;
+}
+
+
void
init_class_processing (void)
{