aboutsummaryrefslogtreecommitdiff
path: root/gcc/java/expr.c
diff options
context:
space:
mode:
authorBryce McKinlay <bryce@albatross.co.nz>2000-03-07 08:58:26 +0000
committerAlexandre Petit-Bianco <apbianco@gcc.gnu.org>2000-03-07 00:58:26 -0800
commit173f556ccc41ea93cf66896d0c7778241467407f (patch)
tree7f5247f181780723c8e8790acc8c5afc9d20e754 /gcc/java/expr.c
parentf2d2acce60eb9ec6ba79c3619a949c84d130b60e (diff)
downloadgcc-173f556ccc41ea93cf66896d0c7778241467407f.zip
gcc-173f556ccc41ea93cf66896d0c7778241467407f.tar.gz
gcc-173f556ccc41ea93cf66896d0c7778241467407f.tar.bz2
decl.c (init_decl_processing): Added new class fields `depth', `ancestors', and `idt' to class_type_node.
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.) From-SVN: r32381
Diffstat (limited to 'gcc/java/expr.c')
-rw-r--r--gcc/java/expr.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/gcc/java/expr.c b/gcc/java/expr.c
index e32b6a9..832e662 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);