diff options
-rw-r--r-- | gcc/java/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/java/class.c | 3 | ||||
-rw-r--r-- | gcc/java/decl.c | 7 | ||||
-rw-r--r-- | gcc/java/expr.c | 35 | ||||
-rw-r--r-- | gcc/java/java-tree.h | 2 | ||||
-rw-r--r-- | gcc/java/parse.y | 2 |
6 files changed, 49 insertions, 14 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index ce13683..9da0e2c 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 f5cfd88..b9f56f5 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 f258ed8..17ec135 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 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); diff --git a/gcc/java/java-tree.h b/gcc/java/java-tree.h index 629061f..e50bab0 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 5406a3b..d1aa061 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: |