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


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

patches for writing .class files


These patches fix two different problems, but both are actual bugs
in generated .class files.  The first would use the wrong instruction
(1-operand ifeq/ifne instead of 2-operand if_icmpeq/if_icmpne) in
switch statements with a single case.  (Rare, which explains why it
wasn't caught before.)

The second problem was in code that changes the "context" class of
an interface method.  It could change it to a non-interface class,
in which we should no longer use invoke_interface.  I also changed
the code to not actually fiddle with (and restore) DECL_CONTEXT,
since that seemed ugly.

I'm checking this into both the trunk and the branch.

2001-04-26  Per Bothner  <per@bothner.com>

	* jcf-write.c (generate_bytecode_insns case SWITCH_EXPR):
	Fix thinko:  If a single case, use if_icmpeq, not ifeq.

	* constants.c (find_methodref_with_class_index):  New function.
	(find_methodref_index):  Use find_methodref_with_class_index.
	* java-tree.h (find_methodref_with_class_index):  New declaration.
	* jcf-write.c (generate_bytecode_insns case CALL_EXPR):  Don't change
	DECL_CONTEXT, instead use new find_methodref_with_class_index function.
	If context changed from interface to class, don't use invokeinterface.

Index: constants.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/constants.c,v
retrieving revision 1.17
diff -u -p -r1.17 constants.c
--- constants.c	2001/02/04 22:44:02	1.17
+++ constants.c	2001/04/26 16:25:33
@@ -197,7 +197,15 @@ find_methodref_index (cpool, decl)
      CPool *cpool;
      tree decl;
 {
-  tree mclass = DECL_CONTEXT (decl);
+  return find_methodref_with_class_index (cpool, decl, DECL_CONTEXT (decl));
+}
+
+int
+find_methodref_with_class_index (cpool, decl, mclass)
+     CPool *cpool;
+     tree decl;
+     tree mclass;
+{
   int class_index = find_class_constant (cpool, mclass);
   tree name = DECL_CONSTRUCTOR_P (decl) ? init_identifier_node
     : DECL_NAME (decl);
Index: jcf-write.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/jcf-write.c,v
retrieving revision 1.72.2.4
diff -u -p -r1.72.2.4 jcf-write.c
--- jcf-write.c	2001/04/04 19:50:43	1.72.2.4
+++ jcf-write.c	2001/04/26 16:25:35
@@ -1721,7 +1721,7 @@ generate_bytecode_insns (exp, target, st
 	      {
 		push_int_const (sw_state.cases->offset, state);
 		emit_if (sw_state.cases->label,
-			 OPCODE_ifeq, OPCODE_ifne, state);
+			 OPCODE_if_icmpeq, OPCODE_if_icmpne, state);
 	      }
 	    emit_goto (sw_state.default_label, state);
 	  }
@@ -2550,7 +2550,7 @@ generate_bytecode_insns (exp, target, st
 	  NOTE_POP (1);  /* Pop implicit this. */
 	if (TREE_CODE (f) == FUNCTION_DECL && DECL_CONTEXT (f) != NULL_TREE)
 	  {
-	    tree saved_context = NULL_TREE;
+	    tree context = DECL_CONTEXT (f);
 	    int index, interface = 0;
 	    RESERVE (5);
 	    if (METHOD_STATIC (f))
@@ -2558,24 +2558,24 @@ generate_bytecode_insns (exp, target, st
 	    else if (DECL_CONSTRUCTOR_P (f) || CALL_USING_SUPER (exp)
 		|| METHOD_PRIVATE (f))
 	      OP1 (OPCODE_invokespecial);
-	    else if (CLASS_INTERFACE (TYPE_NAME (DECL_CONTEXT (f))))
-	      {
-		OP1 (OPCODE_invokeinterface);
-		interface = 1;
-	      }
 	    else
-	      OP1 (OPCODE_invokevirtual);
-	    if (interface)
 	      {
-		saved_context = DECL_CONTEXT (f);
-		DECL_CONTEXT (f) = 
-		  TREE_TYPE (TREE_TYPE (TREE_VALUE (TREE_OPERAND (exp, 1))));
+		if (CLASS_INTERFACE (TYPE_NAME (context)))
+		  {
+		    tree arg1 = TREE_VALUE (TREE_OPERAND (exp, 1));
+		    context = TREE_TYPE (TREE_TYPE (arg1));
+		    if (CLASS_INTERFACE (TYPE_NAME (context)))
+		      interface = 1;
+		  }
+		if (interface)
+		  OP1 (OPCODE_invokeinterface);
+		else
+		  OP1 (OPCODE_invokevirtual);
 	      }
-	    index = find_methodref_index (&state->cpool, f);
+	    index = find_methodref_with_class_index (&state->cpool, f, context);
 	    OP2 (index);
 	    if (interface)
 	      {
-		DECL_CONTEXT (f) = saved_context;
 		if (nargs <= 0)
 		  abort ();
 
Index: java-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/java-tree.h,v
retrieving revision 1.97.2.10
diff -u -p -r1.97.2.10 java-tree.h
--- java-tree.h	2001/04/21 00:06:04	1.97.2.10
+++ java-tree.h	2001/04/26 16:25:36
@@ -1094,6 +1095,7 @@ extern int find_string_constant PARAMS (
 extern int find_class_constant PARAMS ((struct CPool *, tree));
 extern int find_fieldref_index PARAMS ((struct CPool *, tree));
 extern int find_methodref_index PARAMS ((struct CPool *, tree));
+extern int find_methodref_with_class_index PARAMS ((struct CPool *, tree, tree));
 extern void write_constant_pool PARAMS ((struct CPool *, unsigned char *, int));
 extern int count_constant_pool_bytes PARAMS ((struct CPool *));
 extern int encode_newarray_type PARAMS ((tree));

-- 
	--Per Bothner
per@bothner.com   http://www.bothner.com/~per/


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