Commit 60c87482 by Bryce McKinlay Committed by Bryce McKinlay

[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
parent 9450a929
2001-03-23 Bryce McKinlay <bryce@albatross.co.nz>
* extend.texi: Document the "java_interface" attribute.
2001-03-22 Zack Weinberg <zackw@stanford.edu> 2001-03-22 Zack Weinberg <zackw@stanford.edu>
* mkconfig.sh: Use a subshell with redirected stdout, * mkconfig.sh: Use a subshell with redirected stdout,
......
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> 2001-03-22 Richard Henderson <rth@redhat.com>
* Make-lang.in (cp/except.o): Don't depend on insn-flags.h. * Make-lang.in (cp/except.o): Don't depend on insn-flags.h.
......
...@@ -45,6 +45,7 @@ static int equal_functions PARAMS ((tree, tree)); ...@@ -45,6 +45,7 @@ static int equal_functions PARAMS ((tree, tree));
static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int)); static int joust PARAMS ((struct z_candidate *, struct z_candidate *, int));
static int compare_ics PARAMS ((tree, tree)); static int compare_ics PARAMS ((tree, tree));
static tree build_over_call PARAMS ((struct z_candidate *, tree, int)); 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(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) #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)); static tree convert_like_real PARAMS ((tree, tree, tree, int, int));
...@@ -4271,6 +4272,9 @@ build_over_call (cand, args, flags) ...@@ -4271,6 +4272,9 @@ build_over_call (cand, args, flags)
if (TREE_SIDE_EFFECTS (*p)) if (TREE_SIDE_EFFECTS (*p))
*p = save_expr (*p); *p = save_expr (*p);
t = build_pointer_type (TREE_TYPE (fn)); t = build_pointer_type (TREE_TYPE (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)); fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn));
TREE_TYPE (fn) = t; TREE_TYPE (fn) = t;
} }
...@@ -4306,6 +4310,72 @@ build_over_call (cand, args, flags) ...@@ -4306,6 +4310,72 @@ build_over_call (cand, args, flags)
return convert_from_reference (fn); 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 /* Returns the value to use for the in-charge parameter when making a
call to a function with the indicated NAME. */ call to a function with the indicated NAME. */
......
...@@ -1326,6 +1326,7 @@ struct lang_type ...@@ -1326,6 +1326,7 @@ struct lang_type
unsigned has_abstract_assign_ref : 1; unsigned has_abstract_assign_ref : 1;
unsigned non_aggregate : 1; unsigned non_aggregate : 1;
unsigned is_partial_instantiation : 1; unsigned is_partial_instantiation : 1;
unsigned java_interface : 1;
/* When adding a flag here, consider whether or not it ought to /* When adding a flag here, consider whether or not it ought to
apply to a template instance if it applies to the template. If apply to a template instance if it applies to the template. If
...@@ -1334,7 +1335,7 @@ struct lang_type ...@@ -1334,7 +1335,7 @@ struct lang_type
/* There are some bits left to fill out a 32-bit word. Keep track /* 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 of this by updating the size of this bitfield whenever you add or
remove a flag. */ remove a flag. */
unsigned dummy : 9; unsigned dummy : 8;
int vsize; int vsize;
...@@ -1556,6 +1557,10 @@ struct lang_type ...@@ -1556,6 +1557,10 @@ struct lang_type
#define CLASSTYPE_ALIGN_UNIT(NODE) \ #define CLASSTYPE_ALIGN_UNIT(NODE) \
(CLASSTYPE_ALIGN (NODE) / BITS_PER_UNIT) (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 /* A cons list of virtual functions which cannot be inherited by
derived classes. When deriving from this type, the derived derived classes. When deriving from this type, the derived
class must provide its own definition for each of these functions. */ class must provide its own definition for each of these functions. */
......
...@@ -2212,6 +2212,19 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type) ...@@ -2212,6 +2212,19 @@ cp_valid_lang_attribute (attr_name, attr_args, decl, type)
tree decl ATTRIBUTE_UNUSED; tree decl ATTRIBUTE_UNUSED;
tree type 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 (is_attribute_p ("com_interface", attr_name))
{ {
if (! flag_vtable_thunks) if (! flag_vtable_thunks)
......
...@@ -4355,6 +4355,14 @@ changed to be COM-compliant. Also, all classes and structs derived from one ...@@ -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; marked with this attribute are implicitly marked with the same attribute;
thus, only the base class in a COM hierarchy needs @code{com_interface}. 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 @end table
@node Deprecated Features @node Deprecated Features
......
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> 2001-03-21 Alexandre Petit-Bianco <apbianco@redhat.com>
* class.c (layout_class): Fixed push_super_field's second * class.c (layout_class): Fixed push_super_field's second
......
...@@ -1857,7 +1857,12 @@ DEFUN(process_file, (jcf, out), ...@@ -1857,7 +1857,12 @@ DEFUN(process_file, (jcf, out),
generate_access (out, ACC_PUBLIC); generate_access (out, ACC_PUBLIC);
fprintf (out, "\n static ::java::lang::Class class$;\n"); 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) if (append_count > 0)
fputc ('\n', out); fputc ('\n', out);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment