summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>2000-03-07 08:58:26 +0000
committerapbianco <apbianco@138bc75d-0d04-0410-961f-82ee72b054a4>2000-03-07 08:58:26 +0000
commit4095293c7d50d2367f6f60a3d9f8feaa1a932d6d (patch)
tree7f5247f181780723c8e8790acc8c5afc9d20e754
parent261d09344519e41ec72466548567b1460fd2db0c (diff)
downloadppe42-gcc-4095293c7d50d2367f6f60a3d9f8feaa1a932d6d.tar.gz
ppe42-gcc-4095293c7d50d2367f6f60a3d9f8feaa1a932d6d.zip
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
* decl.c (init_decl_processing): Added new class fields `depth', `ancestors', and `idt' to class_type_node. Use _Jv_LookupInterfaceMethodIdx for soft_lookupinterfacemthod_node. * class.c (make_class_data): Push initial values for new fields. * java-tree.h: Updated prototype for `build_invokeinterface'. * expr.c (build_invokeinterface): Changed parameters to accept `method' tree. Calculate index of `method' in its declaring interface. Build call to _Jv_LookupInterfaceMethodIdx. (expand_invoke): Call `build_invokeinterface' with new parameters. * parse.y (patch_invoke): Call `build_invokeinterface' with new parameters. (This is Bryce McKinlay's implementation of the interfaces constant-time dispatch and type checking techniques designed by Per Bothner.) git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@32381 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/java/ChangeLog14
-rw-r--r--gcc/java/class.c3
-rw-r--r--gcc/java/decl.c7
-rw-r--r--gcc/java/expr.c35
-rw-r--r--gcc/java/java-tree.h2
-rw-r--r--gcc/java/parse.y2
6 files changed, 49 insertions, 14 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog
index ce13683245f..9da0e2c12a9 100644
--- a/gcc/java/ChangeLog
+++ b/gcc/java/ChangeLog
@@ -1,3 +1,17 @@
+2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
+
+ * decl.c (init_decl_processing): Added new class fields `depth',
+ `ancestors', and `idt' to class_type_node. Use
+ _Jv_LookupInterfaceMethodIdx for soft_lookupinterfacemthod_node.
+ * class.c (make_class_data): Push initial values for new fields.
+ * java-tree.h: Updated prototype for `build_invokeinterface'.
+ * expr.c (build_invokeinterface): Changed parameters to accept
+ `method' tree. Calculate index of `method' in its declaring
+ interface. Build call to _Jv_LookupInterfaceMethodIdx.
+ (expand_invoke): Call `build_invokeinterface' with new parameters.
+ * parse.y (patch_invoke): Call `build_invokeinterface' with new
+ parameters.
+
2000-03-06 Bryce McKinlay <bryce@albatross.co.nz>
* typeck.c (lookup_do): Search superinterfaces first
diff --git a/gcc/java/class.c b/gcc/java/class.c
index f5cfd880e73..b9f56f5984b 100644
--- a/gcc/java/class.c
+++ b/gcc/java/class.c
@@ -1380,6 +1380,9 @@ make_class_data (type)
PUSH_FIELD_VALUE (cons, "state", integer_zero_node);
PUSH_FIELD_VALUE (cons, "thread", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "depth", integer_zero_node);
+ PUSH_FIELD_VALUE (cons, "ancestors", null_pointer_node);
+ PUSH_FIELD_VALUE (cons, "idt", null_pointer_node);
FINISH_RECORD_CONSTRUCTOR (cons);
diff --git a/gcc/java/decl.c b/gcc/java/decl.c
index f258ed8dc0c..17ec1359064 100644
--- a/gcc/java/decl.c
+++ b/gcc/java/decl.c
@@ -661,6 +661,9 @@ init_decl_processing ()
PUSH_FIELD (class_type_node, field, "interface_count", short_type_node);
PUSH_FIELD (class_type_node, field, "state", byte_type_node);
PUSH_FIELD (class_type_node, field, "thread", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "depth", short_type_node);
+ PUSH_FIELD (class_type_node, field, "ancestors", ptr_type_node);
+ PUSH_FIELD (class_type_node, field, "idt", ptr_type_node);
for (t = TYPE_FIELDS (class_type_node); t != NULL_TREE; t = TREE_CHAIN (t))
FIELD_PRIVATE (t) = 1;
push_super_field (class_type_node, object_type_node);
@@ -815,9 +818,9 @@ init_decl_processing ()
0, NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
- tree_cons (NULL_TREE, ptr_type_node, endlink)));
+ tree_cons (NULL_TREE, int_type_node, endlink)));
soft_lookupinterfacemethod_node
- = builtin_function ("_Jv_LookupInterfaceMethod",
+ = builtin_function ("_Jv_LookupInterfaceMethodIdx",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL_PTR);
t = tree_cons (NULL_TREE, double_type_node,
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index e32b6a9644e..832e662b3e9 100644
--- a/gcc/java/expr.c
+++ b/gcc/java/expr.c
@@ -1648,11 +1648,15 @@ build_invokevirtual (dtable, method)
}
tree
-build_invokeinterface (dtable, method_name, method_signature)
- tree dtable, method_name, method_signature;
+build_invokeinterface (dtable, method)
+ tree dtable, method;
{
static tree class_ident = NULL_TREE;
tree lookup_arg;
+ tree interface;
+ tree idx;
+ tree meth;
+ int i;
/* We expand invokeinterface here. _Jv_LookupInterfaceMethod() will
ensure that the selected method exists, is public and not
@@ -1664,14 +1668,25 @@ build_invokeinterface (dtable, method_name, method_signature)
dtable = build1 (INDIRECT_REF, dtable_type, dtable);
dtable = build (COMPONENT_REF, class_ptr_type, dtable,
lookup_field (&dtable_type, class_ident));
- lookup_arg = build_tree_list (NULL_TREE,
- (build_utf8_ref
- (unmangle_classname
- (IDENTIFIER_POINTER(method_signature),
- IDENTIFIER_LENGTH(method_signature)))));
+
+ interface = DECL_CONTEXT (method);
+
+ i = 1;
+ for (meth = TYPE_METHODS (interface); ; meth = TREE_CHAIN (meth), i++)
+ {
+ if (meth == method)
+ {
+ idx = build_int_2 (i, 0);
+ break;
+ }
+ if (meth == NULL_TREE)
+ fatal ("internal error in build_invokeinterface");
+ }
+
lookup_arg = tree_cons (NULL_TREE, dtable,
- tree_cons (NULL_TREE, build_utf8_ref (method_name),
- lookup_arg));
+ tree_cons (NULL_TREE, build_class_ref (interface),
+ build_tree_list (NULL_TREE, idx)));
+
return build (CALL_EXPR, ptr_type_node,
build_address_of (soft_lookupinterfacemethod_node),
lookup_arg, NULL_TREE);
@@ -1770,7 +1785,7 @@ expand_invoke (opcode, method_ref_index, nargs)
if (opcode == OPCODE_invokevirtual)
func = build_invokevirtual (dtable, method);
else
- func = build_invokeinterface (dtable, method_name, method_signature);
+ func = build_invokeinterface (dtable, method);
}
func = build1 (NOP_EXPR, build_pointer_type (method_type), func);
call = build (CALL_EXPR, TREE_TYPE (method_type), func, arg_list, NULL_TREE);
diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h
index 629061f0e1d..e50bab0b319 100644
--- a/gcc/java/java-tree.h
+++ b/gcc/java/java-tree.h
@@ -564,7 +564,7 @@ extern tree lookup_name PARAMS ((tree));
extern tree build_known_method_ref PARAMS ((tree, tree, tree, tree, tree));
extern tree build_class_init PARAMS ((tree, tree));
extern tree build_invokevirtual PARAMS ((tree, tree));
-extern tree build_invokeinterface PARAMS ((tree, tree, tree));
+extern tree build_invokeinterface PARAMS ((tree, tree));
extern tree invoke_build_dtable PARAMS ((int, tree));
extern tree build_field_ref PARAMS ((tree, tree, tree));
extern void pushdecl_force_head PARAMS ((tree));
diff --git a/gcc/java/parse.y b/gcc/java/parse.y
index 5406a3b432c..d1aa0610e2a 100644
--- a/gcc/java/parse.y
+++ b/gcc/java/parse.y
@@ -7524,7 +7524,7 @@ patch_invoke (patch, method, args)
case INVOKE_INTERFACE:
dtable = invoke_build_dtable (1, args);
- func = build_invokeinterface (dtable, DECL_NAME (method), signature);
+ func = build_invokeinterface (dtable, method);
break;
default:
OpenPOWER on IntegriCloud