PATCH important jc1 fixes

Per Bothner bothner@cygnus.com
Sun Feb 21 15:46:00 GMT 1999


These fix:
(1) My previous patch to force evaluation did not quite work.
With this patch, it seems to.
(2) We used to not do anything about the synchronzed attribute
(when generating native code).  It should now do the Right Thinh.
(3) When generating .class files, we did not generate an Exception
attribute.  This fixes that also.

	--Per Bothner
Cygnus Solutions     bothner@cygnus.com     http://www.cygnus.com/~bothner

Sun Feb 21 14:56:11 1999  Per Bothner  <bothner@cygnus.com>

	* decl.c (build_result_decl), java-tree.h:  New method.
	(complete_start_java_method):  Handle synchronized methods.
	Don't build DECL_RESULT here.  (Ordering dependency problem.)
	(start_java_method):  Call build_result_decl here instead  ...
	* parse.y (java_complete_expand_method):  ... and here.
	(expand_start_java_method): Don't call complete_start_java_method here.
	(java_complete_expand_method):  Call it here instead.
	* parse.h (BUILD_MONITOR_ENTER, BUILD_MONITOR_EXIT):  Moved to ..
	* java-tree.h:  ... here.

	* expr.c (force_evaluation_order):  Fix typo, don't handle ARRAY_REF.
	* parse.y (java_complete_lhs):  Don't call force_evaluation_order
	for ARRAY_REF - it doesn't work when array bounds are checked.
	(patch_array_ref):  Handle it here instead.

	* jcf-write.c (generate_classfile):  Emit "Exceptions" attribute.

Index: decl.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/decl.c,v
retrieving revision 1.66
diff -u -p -r1.66 decl.c
--- decl.c	1999/02/18 21:52:01	1.66
+++ decl.c	1999/02/21 23:31:40
@@ -1465,8 +1465,8 @@ give_name_to_locals (jcf)
     }
 }
 
-void
-complete_start_java_method (fndecl)
+tree
+build_result_decl (fndecl)
   tree fndecl;
 {
   tree restype = TREE_TYPE (TREE_TYPE (fndecl));
@@ -1474,8 +1474,13 @@ complete_start_java_method (fndecl)
   if (INTEGRAL_TYPE_P (restype)
       && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node))
     restype = integer_type_node;
-  DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype);
+  return (DECL_RESULT (fndecl) = build_decl (RESULT_DECL, NULL_TREE, restype));
+}
 
+void
+complete_start_java_method (fndecl)
+  tree fndecl;
+{
   if (! flag_emit_class_files)
     {
       /* Initialize the RTL code for the function.  */
@@ -1509,9 +1514,27 @@ complete_start_java_method (fndecl)
       expand_expr_stmt (init);
     }
 
-  if (METHOD_SYNCHRONIZED (fndecl))
+  if (METHOD_SYNCHRONIZED (fndecl) && ! flag_emit_class_files
+      && DECL_FUNCTION_BODY (fndecl) != NULL_TREE)
     {
-      /* FIXME: surround the function body by a try/finally set.  */
+      /* Warp function body with a monitorenter plus monitorexit cleanup. */
+      tree function_body = DECL_FUNCTION_BODY (fndecl);
+      tree body = BLOCK_EXPR_BODY (function_body);
+      tree enter, exit, lock;
+      if (METHOD_STATIC (fndecl))
+	lock = build_class_ref (DECL_CONTEXT (fndecl));
+      else
+	lock = DECL_ARGUMENTS (fndecl);
+      BUILD_MONITOR_ENTER (enter, lock);
+      BUILD_MONITOR_EXIT (exit, lock);
+      lock = build (WITH_CLEANUP_EXPR, void_type_node,
+		    enter,  NULL_TREE, exit);
+      TREE_SIDE_EFFECTS (lock) = 1;
+      lock = build (COMPOUND_EXPR, TREE_TYPE (body), lock, body);
+      TREE_SIDE_EFFECTS (lock) = 1;
+      lock = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (body), lock);
+      TREE_SIDE_EFFECTS (lock) = 1;
+      BLOCK_EXPR_BODY (function_body) = lock;
     }
 
   /* Push local variables. Function compiled from source code are
@@ -1578,6 +1601,7 @@ start_java_method (fndecl)
   while (i < DECL_MAX_LOCALS(fndecl))
     type_map[i++] = NULL_TREE;
 
+  build_result_decl (fndecl);
   complete_start_java_method (fndecl);
 }
 
Index: expr.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/expr.c,v
retrieving revision 1.88
diff -u -p -r1.88 expr.c
--- expr.c	1999/02/20 00:38:57	1.88
+++ expr.c	1999/02/21 23:31:40
@@ -2492,8 +2492,7 @@ force_evaluation_order (node)
 {
   if (flag_syntax_only)
     return node;
-  if (TREE_CODE_CLASS (TREE_CODE (node)) == '2'
-      && TREE_CODE (node) == ARRAY_REF)
+  if (TREE_CODE_CLASS (TREE_CODE (node)) == '2')
     {
       if (TREE_SIDE_EFFECTS (TREE_OPERAND (node, 1)))
 	TREE_OPERAND (node, 0) = save_expr (TREE_OPERAND (node, 0));
Index: java-tree.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/java-tree.h,v
retrieving revision 1.65
diff -u -p -r1.65 java-tree.h
--- java-tree.h	1999/02/20 00:38:57	1.65
+++ java-tree.h	1999/02/21 23:31:41
@@ -552,6 +552,7 @@ extern int get_access_flags_from_decl PR
 extern int interface_of_p PROTO ((tree, tree));
 extern int inherits_from_p PROTO ((tree, tree));
 extern void complete_start_java_method PROTO ((tree));
+extern tree build_result_decl PROTO ((tree));
 extern void emit_handlers PROTO (());
 extern void init_outgoing_cpool PROTO (());
 extern void make_class_data PROTO ((tree));
@@ -860,6 +861,24 @@ extern tree *type_map;
 
 #define BLOCK_EXPR_DECLS(NODE)  BLOCK_VARS(NODE)
 #define BLOCK_EXPR_BODY(NODE)   BLOCK_SUBBLOCKS(NODE)
+
+#define BUILD_MONITOR_ENTER(WHERE, ARG)				\
+  {								\
+    (WHERE) = build (CALL_EXPR, int_type_node,			\
+		     build_address_of (soft_monitorenter_node),	\
+		     build_tree_list (NULL_TREE, (ARG)), 	\
+		     NULL_TREE);				\
+    TREE_SIDE_EFFECTS (WHERE) = 1;				\
+  }
+
+#define BUILD_MONITOR_EXIT(WHERE, ARG)				\
+  {								\
+    (WHERE) = build (CALL_EXPR, int_type_node,			\
+		     build_address_of (soft_monitorexit_node),	\
+		     build_tree_list (NULL_TREE, (ARG)),	\
+		     NULL_TREE);				\
+    TREE_SIDE_EFFECTS (WHERE) = 1;				\
+  }
 
 /* Non zero if TYPE is an unchecked exception */
 #define IS_UNCHECKED_EXCEPTION_P(TYPE)				\
Index: jcf-write.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/jcf-write.c,v
retrieving revision 1.19
diff -u -p -r1.19 jcf-write.c
--- jcf-write.c	1999/02/19 20:36:10	1.19
+++ jcf-write.c	1999/02/21 23:31:41
@@ -2760,7 +2760,8 @@ generate_classfile (clas, state)
       i = find_utf8_constant (&state->cpool, name);  PUT2 (i);
       i = find_utf8_constant (&state->cpool, build_java_signature (type));
       PUT2 (i);
-      PUT2 (body != NULL_TREE ? 1 : 0);   /* attributes_count */
+      i = (body != NULL_TREE) + (DECL_FUNCTION_THROWS (part) != NULL_TREE);
+      PUT2 (i);   /* attributes_count */
       if (body != NULL_TREE)
 	{
 	  int code_attributes_count = 0;
@@ -2874,6 +2875,24 @@ generate_classfile (clas, state)
 		  i = find_utf8_constant (&state->cpool, sig);  PUT2 (i);
 		  i = DECL_LOCAL_INDEX (lvar->decl);  PUT2 (i);
 		}
+	    }
+	}
+      if (DECL_FUNCTION_THROWS (part) != NULL_TREE)
+	{
+	  tree t = DECL_FUNCTION_THROWS (part);
+	  int throws_count = list_length (t);
+	  static tree Exceptions_node = NULL_TREE;
+	  if (Exceptions_node == NULL_TREE)
+	    Exceptions_node = get_identifier ("Exceptions");
+	  ptr = append_chunk (NULL, 8 + 2 * throws_count, state);
+	  i = find_utf8_constant (&state->cpool, Exceptions_node);
+	  PUT2 (i);  /* attribute_name_index */ 
+	  i = 2 + 2 * throws_count;  PUT4(i); /* attribute_length */ 
+	  i = throws_count;  PUT2 (i); 
+	  for (;  t != NULL_TREE;  t = TREE_CHAIN (t))
+	    {
+	      i = find_class_constant (&state->cpool, TREE_VALUE (t));
+	      PUT2 (i);
 	    }
 	}
       methods_count++;
Index: parse.h
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/parse.h,v
retrieving revision 1.39
diff -u -p -r1.39 parse.h
--- parse.h	1999/02/19 22:59:23	1.39
+++ parse.h	1999/02/21 23:31:41
@@ -509,24 +509,6 @@ static jdeplist *reverse_jdep_list ();
 			(ARG ? build_tree_list (NULL, (ARG)) : NULL_TREE))
 
 /* For exception handling, build diverse function calls */
-#define BUILD_MONITOR_ENTER(WHERE, ARG)				\
-  {								\
-    (WHERE) = build (CALL_EXPR, int_type_node,			\
-		     build_address_of (soft_monitorenter_node),	\
-		     build_tree_list (NULL_TREE, (ARG)), 	\
-		     NULL_TREE);				\
-    TREE_SIDE_EFFECTS (WHERE) = 1;				\
-  }
-
-#define BUILD_MONITOR_EXIT(WHERE, ARG)				\
-  {								\
-    (WHERE) = build (CALL_EXPR, int_type_node,			\
-		     build_address_of (soft_monitorexit_node),	\
-		     build_tree_list (NULL_TREE, (ARG)),	\
-		     NULL_TREE);				\
-    TREE_SIDE_EFFECTS (WHERE) = 1;				\
-  }
-
 #define BUILD_ASSIGN_EXCEPTION_INFO(WHERE, TO)		\
   {							\
     (WHERE) = build (MODIFY_EXPR, void_type_node, (TO),	\
Index: parse.y
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/java/parse.y,v
retrieving revision 1.53
diff -u -p -r1.53 parse.y
--- parse.y	1999/02/20 00:38:57	1.53
+++ parse.y	1999/02/21 23:31:41
@@ -5464,7 +5464,6 @@ expand_start_java_method (fndecl)
   *ptr = NULL_TREE;
   pushdecl_force_head (DECL_ARGUMENTS (fndecl));
   lineno = DECL_SOURCE_LINE_FIRST (fndecl);
-  complete_start_java_method (fndecl); 
 }
 
 /* Terminate a function and expand its body.  */
@@ -5731,6 +5730,7 @@ java_complete_expand_method (mdecl)
       tree fbody = DECL_FUNCTION_BODY (mdecl);
       tree block_body = BLOCK_EXPR_BODY (fbody);
       expand_start_java_method (mdecl);
+      build_result_decl (mdecl);
 
       current_this 
 	= (!METHOD_STATIC (mdecl) ? 
@@ -5753,6 +5753,8 @@ java_complete_expand_method (mdecl)
 	  && TREE_CODE (TREE_TYPE (TREE_TYPE (mdecl))) != VOID_TYPE)
 	missing_return_error (current_function_decl);
 
+      complete_start_java_method (mdecl); 
+
       /* Don't go any further if we've found error(s) during the
          expansion */
       if (!java_error_count)
@@ -8053,7 +8055,7 @@ java_complete_lhs (node)
 	return error_mark_node;
       if (!flag_emit_class_files)
 	TREE_OPERAND (node, 1) = save_expr (TREE_OPERAND (node, 1));
-      return force_evaluation_order (patch_array_ref (node));
+      return patch_array_ref (node);
 
     case RECORD_TYPE:
       return node;;
@@ -9886,7 +9888,16 @@ patch_array_ref (node)
       TREE_OPERAND (node, 1) = index;
     }
   else
-    node = build_java_arrayaccess (array, array_type, index);
+    {
+      /* The save_expr is for correct evaluation order.  It would be cleaner
+	 to use force_evaluation_order (see comment there), but that is
+	 difficult when we also have to deal with bounds checking. */
+      if (TREE_SIDE_EFFECTS (index))
+	array = save_expr (array);
+      node = build_java_arrayaccess (array, array_type, index);
+      if (TREE_SIDE_EFFECTS (index))
+	node = build (COMPOUND_EXPR, array_type, array, node);
+    }
   TREE_TYPE (node) = array_type;
   return node;
 }


More information about the Gcc-patches mailing list