* [gcjx] Patch: FYI: array store checks
@ 2005-10-12 21:17 Tom Tromey
0 siblings, 0 replies; only message in thread
From: Tom Tromey @ 2005-10-12 21:17 UTC (permalink / raw)
To: Java Patch List
I'm checking this in on the gcjx branch.
This adds array store checking to the generated code.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* tree.hh (tree_generator::handle_array_ref): Declare.
(tree_generator::build_array_reference): Added argument.
* tree.cc (handle_array_ref): New method
(visit_array_ref): Use it.
(build_array_reference): Added 'rhs' argument. Emit call to
_Jv_CheckArrayStore.
(visit_assignment): Special case assignment to an array element.
(handle_op_assignment): Likewise.
Index: tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.67
diff -u -r1.1.2.67 tree.cc
--- tree.cc 12 Oct 2005 15:20:21 -0000 1.1.2.67
+++ tree.cc 12 Oct 2005 21:16:41 -0000
@@ -1194,9 +1194,10 @@
}
void
-tree_generator::visit_array_ref (model_array_ref *aref,
- const ref_expression &array,
- const ref_expression &index)
+tree_generator::handle_array_ref (model_array_ref *aref,
+ model_expression *array,
+ model_expression *index,
+ tree rhs)
{
array->visit (this);
tree array_tree = current;
@@ -1208,11 +1209,20 @@
// FIXME: this should be handled more generically.
gcc_builtins->lay_out_class (assert_cast<model_class *> (array->type ()));
- current = build_array_reference (array_tree, index_tree, component_type);
+ current = build_array_reference (array_tree, index_tree, component_type,
+ true, rhs);
annotate (current, aref);
}
void
+tree_generator::visit_array_ref (model_array_ref *aref,
+ const ref_expression &array,
+ const ref_expression &index)
+{
+ handle_array_ref (aref, array.get (), index.get ());
+}
+
+void
tree_generator::binary_operator (model_element *element,
tree_code code,
const ref_expression &lhs,
@@ -1565,11 +1575,24 @@
const ref_expression &lhs,
const ref_expression &rhs)
{
- lhs->visit (this);
- tree lhs_tree = current;
+ // It is ok to visit the RHS first, since we don't keep much state
+ // in this class.
rhs->visit (this);
tree rhs_tree = current;
- // FIXME: if LHS is array, may need assign. check.
+
+ // This is pretty ugly, but it is reasonably simple to do this as a
+ // special case here. If we see an array reference on the LHS, we
+ // must emit a check as well. Note that we don't need a check if
+ // the RHS is 'null' or if the array has primitive type.
+ model_array_ref *ref = dynamic_cast<model_array_ref *> (lhs.get ());
+ if (ref != NULL
+ && rhs->type () != null_type
+ && ref->type ()->reference_p ())
+ handle_array_ref (ref, ref->get_array (), ref->get_index (), rhs_tree);
+ else
+ lhs->visit (this);
+ tree lhs_tree = current;
+
current = build2 (MODIFY_EXPR, TREE_TYPE (lhs_tree),
lhs_tree, convert (TREE_TYPE (lhs_tree), rhs_tree));
TREE_SIDE_EFFECTS (current) = 1;
@@ -1582,11 +1605,24 @@
const ref_expression &lhs,
const ref_expression &rhs)
{
- lhs->visit (this);
- tree lhs_tree = stabilize_reference (current);
+ // It is ok to visit the RHS first, since we don't keep much state
+ // in this class.
rhs->visit (this);
tree rhs_tree = current;
+ // This is pretty ugly, but it is reasonably simple to do this as a
+ // special case here. If we see an array reference on the LHS, we
+ // must emit a check as well. Note that we don't need a check if
+ // the RHS is 'null' or if the array has primitive type.
+ model_array_ref *ref = dynamic_cast<model_array_ref *> (lhs.get ());
+ if (ref != NULL
+ && rhs->type () != null_type
+ && ref->type ()->reference_p ())
+ handle_array_ref (ref, ref->get_array (), ref->get_index (), rhs_tree);
+ else
+ lhs->visit (this);
+ tree lhs_tree = current;
+
bool is_shift = (op == LSHIFT_EXPR || op == RSHIFT_EXPR);
// Note that we convert the LHS to the type of the RHS, because the
@@ -2673,7 +2709,8 @@
tree
tree_generator::build_array_reference (tree array, tree index,
tree result_type,
- bool use_checks)
+ bool use_checks,
+ tree rhs)
{
tree array_type = TREE_TYPE (TREE_TYPE (array));
// Note that the 'data' field is a back-end invention; it does not
@@ -2694,6 +2731,22 @@
TREE_SIDE_EFFECTS (result) = (TREE_SIDE_EFFECTS (array)
|| TREE_SIDE_EFFECTS (index));
+ // The bounds check takes precedence over the array store check, but
+ // we are building things bottom-up, so we construct the array store
+ // check first.
+ if (rhs != NULL_TREE)
+ {
+ tree call = build3 (CALL_EXPR, void_type_node,
+ builtin_Jv_CheckArrayStore,
+ tree_cons (NULL_TREE, array,
+ build_tree_list (NULL_TREE, rhs)),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
+
+ result = build2 (COMPOUND_EXPR, result_type, call, result);
+ TREE_SIDE_EFFECTS (result) = 1;
+ }
+
if (use_checks && flag_bounds_check)
{
tree field = gcc_builtins->find_decl (array_type, "length");
Index: tree.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.hh,v
retrieving revision 1.1.2.21
diff -u -r1.1.2.21 tree.hh
--- tree.hh 12 Oct 2005 19:10:12 -0000 1.1.2.21
+++ tree.hh 12 Oct 2005 21:16:41 -0000
@@ -130,11 +130,13 @@
model_type *find_model_class (const std::string &);
tree build_divide (tree, tree, tree);
tree build_mod (tree, tree, tree);
- tree build_array_reference (tree, tree, tree, bool = true);
+ tree build_array_reference (tree, tree, tree, bool = true, tree = NULL_TREE);
tree build_exception_object_ref (tree);
tree build_label ();
tree make_block ();
tree build_arguments (const std::list<ref_expression> &, tree &);
+ void handle_array_ref (model_array_ref *, model_expression *,
+ model_expression *, tree = NULL_TREE);
void stringbuffer_append (model_expression *, tree &, model_class *,
tree = NULL_TREE);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2005-10-12 21:17 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-10-12 21:17 [gcjx] Patch: FYI: array store checks Tom Tromey
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).