[multiple changes]

2001-03-23  Bryce McKinlay  <bryce@albatross.co.nz>

	* extend.texi: Document the "java_interface" attribute.

java/:
2001-03-21  Bryce McKinlay  <bryce@albatross.co.nz>

	* gjavah.c (process_file): Mark interface definitions with
	"__attribute__ ((java_interface))".

cp/:
2001-03-22  Bryce McKinlay  <bryce@albatross.co.nz>

	Add support for Java interface method calls.
	* cp-tree.h (struct lang_type): Add java_interface flag.
	(TYPE_JAVA_INTERFACE): New macro.
	* tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
	by setting TYPE_JAVA_INTERFACE.
	* call.c (java_iface_lookup_fn): New static.
	(build_over_call): If calling a method declared in a
	TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
	expression which resolves the function address.
	(build_java_interface_fn_ref): New function.

From-SVN: r40769
This commit is contained in:
Bryce McKinlay 2001-03-23 01:49:11 +00:00 committed by Bryce McKinlay
parent 9450a9295b
commit 60c8748279
8 changed files with 126 additions and 3 deletions

View File

@ -1,3 +1,7 @@
2001-03-23 Bryce McKinlay <bryce@albatross.co.nz>
* extend.texi: Document the "java_interface" attribute.
2001-03-22 Zack Weinberg <zackw@stanford.edu>
* mkconfig.sh: Use a subshell with redirected stdout,

View File

@ -1,3 +1,16 @@
2001-03-22 Bryce McKinlay <bryce@albatross.co.nz>
Add support for Java interface method calls.
* cp-tree.h (struct lang_type): Add java_interface flag.
(TYPE_JAVA_INTERFACE): New macro.
* tree.c (cp_valid_lang_attribute): Handle "java_interface" attribute
by setting TYPE_JAVA_INTERFACE.
* call.c (java_iface_lookup_fn): New static.
(build_over_call): If calling a method declared in a
TYPE_JAVA_INTERFACE, call build_java_interface_fn_ref to generate the
expression which resolves the function address.
(build_java_interface_fn_ref): New function.
2001-03-22 Richard Henderson <rth@redhat.com>
* Make-lang.in (cp/except.o): Don't depend on insn-flags.h.

View File

@ -45,6 +45,7 @@ static int equal_functions PARAMS ((tree, tree));
static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
static int compare_ics PARAMS ((tree, tree));
static tree build_over_call PARAMS ((struct z_candidate *, tree, int));
static tree build_java_interface_fn_ref PARAMS ((tree, tree));
#define convert_like(CONV, EXPR) convert_like_real (CONV, EXPR, NULL_TREE, 0, 0)
#define convert_like_with_context(CONV, EXPR, FN, ARGNO) convert_like_real (CONV, EXPR, FN, ARGNO, 0)
static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
@ -4271,7 +4272,10 @@ build_over_call (cand, args, flags)
if (TREE_SIDE_EFFECTS (*p))
*p = save_expr (*p);
t = build_pointer_type (TREE_TYPE (fn));
fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
if (DECL_CONTEXT (fn) && TYPE_JAVA_INTERFACE (DECL_CONTEXT (fn)))
fn = build_java_interface_fn_ref (fn, *p);
else
fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
TREE_TYPE (fn) = t;
}
else if (DECL_INLINE (fn))
@ -4306,6 +4310,72 @@ build_over_call (cand, args, flags)
return convert_from_reference (fn);
}
static tree java_iface_lookup_fn;
/* Make an expression which yields the address of the Java interface
method FN. This is achieved by generating a call to libjava's
_Jv_LookupInterfaceMethodIdx(). */
static tree
build_java_interface_fn_ref (fn, instance)
tree fn, instance;
{
tree lookup_args, lookup_fn, method, idx;
tree klass_ref, iface, iface_ref;
int i;
if (!java_iface_lookup_fn)
{
tree endlink = build_void_list_node ();
tree t = tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, ptr_type_node,
tree_cons (NULL_TREE, java_int_type_node,
endlink)));
java_iface_lookup_fn
= builtin_function ("_Jv_LookupInterfaceMethodIdx",
build_function_type (ptr_type_node, t),
0, NOT_BUILT_IN, NULL_PTR);
ggc_add_tree_root (&java_iface_lookup_fn, 1);
}
/* Look up the pointer to the runtime java.lang.Class object for `instance'.
This is the first entry in the vtable. */
klass_ref = build_vtbl_ref (build_indirect_ref (instance, 0),
integer_zero_node);
/* Get the java.lang.Class pointer for the interface being called. */
iface = DECL_CONTEXT (fn);
iface_ref = lookup_field (iface, get_identifier ("class$"), 0, 0);
if (!iface_ref || TREE_CODE (iface_ref) != VAR_DECL
|| DECL_CONTEXT (iface_ref) != iface)
{
cp_error ("Could not find class$ field in java interface type `%T'",
iface);
return error_mark_node;
}
iface_ref = build1 (ADDR_EXPR, build_pointer_type (iface), iface_ref);
/* Determine the itable index of FN. */
i = 1;
for (method = TYPE_METHODS (iface); method; method = TREE_CHAIN (method))
{
if (!DECL_VIRTUAL_P (method))
continue;
if (fn == method)
break;
i++;
}
idx = build_int_2 (i, 0);
lookup_args = tree_cons (NULL_TREE, klass_ref,
tree_cons (NULL_TREE, iface_ref,
build_tree_list (NULL_TREE, idx)));
lookup_fn = build1 (ADDR_EXPR,
build_pointer_type (TREE_TYPE (java_iface_lookup_fn)),
java_iface_lookup_fn);
return build (CALL_EXPR, ptr_type_node, lookup_fn, lookup_args, NULL_TREE);
}
/* Returns the value to use for the in-charge parameter when making a
call to a function with the indicated NAME. */

View File

@ -1326,6 +1326,7 @@ struct lang_type
unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1;
unsigned java_interface : 1;
/* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If
@ -1334,7 +1335,7 @@ struct lang_type
/* There are some bits left to fill out a 32-bit word. Keep track
of this by updating the size of this bitfield whenever you add or
remove a flag. */
unsigned dummy : 9;
unsigned dummy : 8;
int vsize;
@ -1556,6 +1557,10 @@ struct lang_type
#define CLASSTYPE_ALIGN_UNIT(NODE) \
(CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT)
/* True if this a Java interface type, declared with
'__attribute__ ((java_interface))'. */
#define TYPE_JAVA_INTERFACE(NODE) (TYPE_LANG_SPECIFIC(NODE)->java_interface)
/* A cons list of virtual functions which cannot be inherited by
derived classes. When deriving from this type, the derived
class must provide its own definition for each of these functions. */

View File

@ -2212,6 +2212,19 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
tree decl ATTRIBUTE_UNUSED;
tree type ATTRIBUTE_UNUSED;
{
if (is_attribute_p ("java_interface", attr_name))
{
if (attr_args != NULL_TREE
|| decl != NULL_TREE
|| ! CLASS_TYPE_P (type)
|| ! TYPE_FOR_JAVA (type))
{
error ("`java_interface' attribute can only be applied to Java class definitions");
return 0;
}
TYPE_JAVA_INTERFACE (type) = 1;
return 1;
}
if (is_attribute_p ("com_interface", attr_name))
{
if (! flag_vtable_thunks)

View File

@ -4355,6 +4355,14 @@ changed to be COM-compliant. Also, all classes and structs derived from one
marked with this attribute are implicitly marked with the same attribute;
thus, only the base class in a COM hierarchy needs @code{com_interface}.
@item java_interface
@cindex java_interface attribute
This type attribute informs C++ that the class is a Java interface. It may
only be applied to classes declared within an @code{extern "Java"} block.
Calls to methods declared in this interface will be dispatched using GCJ's
interface table mechanism, instead of regular virtual table dispatch.
@end table
@node Deprecated Features

View File

@ -1,3 +1,8 @@
2001-03-21 Bryce McKinlay <bryce@albatross.co.nz>
* gjavah.c (process_file): Mark interface definitions with
"__attribute__ ((java_interface))".
2001-03-21 Alexandre Petit-Bianco <apbianco@redhat.com>
* class.c (layout_class): Fixed push_super_field's second

View File

@ -1857,7 +1857,12 @@ DEFUN(process_file, (jcf, out),
generate_access (out, ACC_PUBLIC);
fprintf (out, "\n static ::java::lang::Class class$;\n");
fputs ("};\n", out);
fputs ("}", out);
if (jcf->access_flags & ACC_INTERFACE)
fputs (" __attribute__ ((java_interface))", out);
fputs (";\n", out);
if (append_count > 0)
fputc ('\n', out);