This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
patches for writing .class files
- To: gcc-patches at gcc dot gnu dot org, java-patches at gcc dot gnu dot org
- Subject: patches for writing .class files
- From: Per Bothner <per at bothner dot com>
- Date: 26 Apr 2001 11:43:50 -0700
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/