public inbox for java-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [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).