This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

patch to java/verify.c


I checked the attached patch into the trunk.  The patches have
been sitting in my source tree for a while.  Both came from work
on Kawa.

I think the patch dealing with subroutine (jsr) nesting came
from a bug while I was implementing XQuery, the draft XML query
language from W3C (see http://www.gnu.org/software/kawa/query/).
XQuery has 'for' loops that are similar to SQL's 'select'.
I compile the body of the 'for' loop into a jsr/ret subroutine.
(I can't just inline it because sometimes there are multiple places
where the code can execute the body, due to other optimizations.)
This may be the first interesting case where Java bytecodes can
express something useful that you you can't express in Java source
without substantial convolution or overhead.  (I'd be curious to
see what a JVM disassembler does with it!)
-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/per/
Index: ChangeLog
2001-12-03  Per Bothner  <per@bothner.com>

	* verify.c (subroutine_nesting):  New function.
	(verify_jvm_instructions):  Use it to fix logic for checking that
	we're done with the current subroutine.

	* verify.c (verify_jvm_instruction): For OPCODE_checkcast and
	OPCODE_instanceof use POP_TYPE macro for better diagnostics.

Index: verify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/verify.c,v
retrieving revision 1.45
diff -u -p -r1.45 verify.c
--- verify.c	2001/09/14 00:16:36	1.45
+++ verify.c	2001/12/03 23:15:04
@@ -104,6 +104,22 @@ check_pending_block (target_label)
   return NULL;
 }
 
+/* Count the number of nested jsr calls needed to reach LABEL. */
+
+static int
+subroutine_nesting (tree label)
+{
+  int nesting = 0;
+  while (label != NULL_TREE && LABEL_IN_SUBR (label))
+    {
+      if (! LABEL_IS_SUBR_START(label))
+	label = LABEL_SUBR_START (label);
+      label = LABEL_SUBR_CONTEXT (label);
+      nesting++;
+    }
+  return nesting;
+}
+
 /* Return the "merged" types of TYPE1 and TYPE2.
    If either is primitive, the other must match (after promotion to int).
    For reference types, return the common super-class.
@@ -497,11 +513,9 @@ verify_jvm_instructions (jcf, byte_ops, 
       if (current_subr 
 	  && PC == INVALID_PC)
 	{
-	  tree caller = LABEL_SUBR_CONTEXT (current_subr);
-
 	  if (pending_blocks == NULL_TREE
-	      || ! LABEL_IN_SUBR (pending_blocks)
-	      || LABEL_SUBR_START (pending_blocks) == caller)
+	      || (subroutine_nesting (pending_blocks)
+		  < subroutine_nesting (current_subr)))
 	    {
 	      int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
 	      tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
@@ -511,7 +525,7 @@ verify_jvm_instructions (jcf, byte_ops, 
 		 have returned to an earlier caller.  Obviously a
 		 "ret" can only return one level, but a throw may
 		 return many levels.*/
-	      current_subr = caller;
+	      current_subr = LABEL_SUBR_CONTEXT (current_subr);
 
 	      if (RETURN_MAP_ADJUSTED (ret_map))
 		{
@@ -1174,12 +1188,14 @@ verify_jvm_instructions (jcf, byte_ops, 
 	  break;
 
 	case OPCODE_checkcast:
-	  pop_type (ptr_type_node);
+	  POP_TYPE (object_ptr_type_node,
+		    "checkcast operand is not a pointer");
 	  type = get_class_constant (current_jcf, IMMEDIATE_u2);
 	  PUSH_TYPE (type);
 	  break;
 	case OPCODE_instanceof:
-	  pop_type (ptr_type_node);
+	  POP_TYPE (object_ptr_type_node,
+		    "instanceof operand is not a pointer");
 	  get_class_constant (current_jcf, IMMEDIATE_u2);
 	  PUSH_TYPE (int_type_node);
 	  break;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]