This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: boxing and unboxing
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 03 Apr 2005 18:45:49 -0600
- Subject: [gcjx] Patch: FYI: boxing and unboxing
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This adds support for boxing and unboxing conversions to the tree
back end.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* tree.cc (visit_cast): Handle boxing and unboxing.
Index: tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.38
diff -u -r1.1.2.38 tree.cc
--- tree.cc 3 Apr 2005 23:47:45 -0000 1.1.2.38
+++ tree.cc 4 Apr 2005 00:46:37 -0000
@@ -1611,20 +1611,53 @@
expr->visit (this);
tree expr_tree = current;
- if (dest->type ()->primitive_p ())
+ model_type *dest_type = dest->type ();
+ if (dest_type->primitive_p () != expr->type ()->primitive_p ())
+ {
+ if (dest_type->primitive_p ())
+ {
+ // Unboxing conversion. Call <type>Value() on the wrapper
+ // object, e.g. for Integer we call intValue(). Using
+ // get_pretty_name here is a bit of an abuse.
+ // FIXME: for the C++ ABI we could reference fields directly
+ // in some situations.
+ std::string method_name = dest_type->get_pretty_name () + "Value";
+ model_method *call
+ = find_method (method_name.c_str (),
+ assert_cast<model_class *> (expr->type ()),
+ NULL, dest_type, elt);
+ current = gcc_builtins->map_method_call (class_wrapper, expr_tree,
+ NULL_TREE, call, false);
+ }
+ else
+ {
+ // Boxing conversion. We call the static factory method
+ // valueOf(), which handles the caching required by boxing
+ // conversion.
+ model_class *dest_class = assert_cast<model_class *> (dest_type);
+ model_method *call = find_method ("valueOf", dest_class,
+ expr->type (), dest_class,
+ elt);
+ tree args = build_tree_list (NULL_TREE, expr_tree);
+ current = gcc_builtins->map_method_call (class_wrapper, NULL_TREE,
+ args, call, false);
+ TREE_SIDE_EFFECTS (current) = 1;
+ }
+ }
+ else if (dest_type->primitive_p ())
{
// We can't use fold_convert() here since, apparently, it can't
// convert a float to an int.
- current = convert (gcc_builtins->map_type (dest->type ()), expr_tree);
+ current = convert (gcc_builtins->map_type (dest_type), expr_tree);
TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
}
else
{
// Reference types. We only need to emit a cast check if the
// types are known to be incompatible.
- if (dest->type ()->assignable_from_p (expr->type ()))
+ if (dest_type->assignable_from_p (expr->type ()))
{
- current = build3 (CALL_EXPR, gcc_builtins->map_type (dest->type ()),
+ current = build3 (CALL_EXPR, gcc_builtins->map_type (dest_type),
builtin_Jv_CheckCast,
build_tree_list (NULL_TREE, expr_tree),
NULL_TREE);
@@ -1632,8 +1665,8 @@
}
else
{
- emit_type_assertion (dest->type (), expr->type ());
- current = build1 (NOP_EXPR, gcc_builtins->map_type (dest->type ()),
+ emit_type_assertion (dest_type, expr->type ());
+ current = build1 (NOP_EXPR, gcc_builtins->map_type (dest_type),
expr_tree);
TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
}