This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: handle invoke_* opcodes
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 03 Apr 2005 18:50:59 -0600
- Subject: [gcjx] Patch: FYI: handle invoke_* opcodes
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This adds support for the invoke_* opcodes when lowering from
bytecode to trees.
Tom
Index: gcjx/ChangeLog
from Tom Tromey <tromey@redhat.com>
* bytecode/cpool.cc (get_methodref): New method.
* bytecode/cpool.hh (constant_pool::get_methodref): Declare.
Index: gcc/java/ChangeLog
from Tom Tromey <tromey@redhat.com>
* abi.cc (build_method_call): New stubs.
(build_field_reference): Likewise.
* abi.hh (gcj_abi::build_method_call): Declare new overload.
(gcj_abi::build_field_reference): Likewise.
(cxx_abi::build_method_call): Declare.
(cxx_abi::build_field_reference): Likewise.
(bc_abi::build_method_call): Declare.
(bc_abi::build_field_reference): Likewise.
* builtins.cc (map_method_call): New method.
(map_field_ref): Wrote.
* builtins.hh (tree_builtins::map_method_call): Declare new
overload.
* lower.cc (visit_bytecode_block): Handle invoke_* opcodes. Set
TREE_SIDE_EFFECTS in more places.
Index: gcjx/bytecode/cpool.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/cpool.cc,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 cpool.cc
--- gcjx/bytecode/cpool.cc 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ gcjx/bytecode/cpool.cc 4 Apr 2005 00:51:08 -0000
@@ -1,6 +1,6 @@
// Constant pool.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -67,8 +67,22 @@
std::string &descriptor)
{
if (! valid_p (index) || tag (index) != CONSTANT_Fieldref)
- throw class_file_error (where, "expected CONSTANT_Fieldref tag at index %1")
+ throw class_file_error (where, "expected CONSTANT_Fieldref tag "
+ "at index %1")
% int (index);
class_name = get_class (value (index) & 0xffff);
get_name_and_type ((value (index) >> 16) & 0xffff, field_name, descriptor);
}
+
+void
+constant_pool::get_methodref (uint16 index, std::string &class_name,
+ std::string &method_name,
+ std::string &descriptor)
+{
+ if (! valid_p (index) || tag (index) != CONSTANT_Methodref)
+ throw class_file_error (where, "expected CONSTANT_Methodref tag "
+ "at index %1")
+ % int (index);
+ class_name = get_class (value (index) & 0xffff);
+ get_name_and_type ((value (index) >> 16) & 0xffff, method_name, descriptor);
+}
Index: gcjx/bytecode/cpool.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcjx/bytecode/Attic/cpool.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 cpool.hh
--- gcjx/bytecode/cpool.hh 13 Jan 2005 03:18:34 -0000 1.1.2.1
+++ gcjx/bytecode/cpool.hh 4 Apr 2005 00:51:08 -0000
@@ -1,6 +1,6 @@
// Constant pool.
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
@@ -95,6 +95,7 @@
std::string get_class (uint16);
void get_fieldref (uint16, std::string &, std::string &, std::string &);
+ void get_methodref (uint16, std::string &, std::string &, std::string &);
};
#endif // GCJX_BYTECODE_CPOOL_HH
Index: gcc/java/abi.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.cc,v
retrieving revision 1.1.2.21
diff -u -r1.1.2.21 abi.cc
--- gcc/java/abi.cc 3 Apr 2005 23:52:15 -0000 1.1.2.21
+++ gcc/java/abi.cc 4 Apr 2005 00:51:16 -0000
@@ -156,6 +156,17 @@
}
tree
+cxx_abi::build_method_call (tree_builtins *builtins,
+ aot_class *current,
+ tree obj, tree args,
+ const std::string &class_name,
+ const std::string &method_name,
+ const std::string &descriptor)
+{
+ abort (); // FIXME
+}
+
+tree
cxx_abi::build_field_reference (tree_builtins *builtins,
aot_class *,
tree obj, model_field *field)
@@ -185,6 +196,17 @@
}
tree
+cxx_abi::build_field_reference (tree_builtins *builtins,
+ aot_class *current,
+ tree obj,
+ const std::string &classname,
+ const std::string &fieldname,
+ const std::string &descriptor)
+{
+ abort (); // FIXME
+}
+
+tree
cxx_abi::build_class_reference (tree_builtins *builtins,
aot_class *current,
const std::string &classname)
@@ -411,6 +433,17 @@
}
tree
+bc_abi::build_method_call (tree_builtins *builtins,
+ aot_class *current,
+ tree obj, tree args,
+ const std::string &class_name,
+ const std::string &method_name,
+ const std::string &descriptor)
+{
+ abort (); // FIXME
+}
+
+tree
bc_abi::build_field_reference (tree_builtins *builtins, aot_class *current,
tree obj, model_field *field)
{
@@ -455,6 +488,17 @@
}
tree
+bc_abi::build_field_reference (tree_builtins *builtins,
+ aot_class *current,
+ tree obj,
+ const std::string &classname,
+ const std::string &fieldname,
+ const std::string &descriptor)
+{
+ abort (); // FIXME
+}
+
+tree
bc_abi::build_class_reference (tree_builtins *builtins, aot_class *current,
const std::string &classname)
{
Index: gcc/java/abi.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.hh,v
retrieving revision 1.1.2.9
diff -u -r1.1.2.9 abi.hh
--- gcc/java/abi.hh 3 Apr 2005 23:50:05 -0000 1.1.2.9
+++ gcc/java/abi.hh 4 Apr 2005 00:51:16 -0000
@@ -78,12 +78,26 @@
tree obj, tree args, model_method *meth,
bool is_super) = 0;
+ virtual tree build_method_call (tree_builtins *builtins,
+ aot_class *current,
+ tree obj, tree args,
+ const std::string &class_name,
+ const std::string &method_name,
+ const std::string &descriptor) = 0;
+
/// Note that we explicitly do not handle a non-static reference to
/// a static field. That must be handled by the caller.
virtual tree build_field_reference (tree_builtins *builtins,
aot_class *current,
tree obj, model_field *field) = 0;
+ virtual tree build_field_reference (tree_builtins *builtins,
+ aot_class *current,
+ tree obj,
+ const std::string &classname,
+ const std::string &fieldname,
+ const std::string &descriptor) = 0;
+
/// Return a tree representing a reference to some other class.
virtual tree build_class_reference (tree_builtins *builtins,
aot_class *current,
@@ -140,9 +154,23 @@
tree build_method_call (tree_builtins *, aot_class *,
tree, tree, model_method *, bool);
+ tree build_method_call (tree_builtins *builtins,
+ aot_class *current,
+ tree obj, tree args,
+ const std::string &class_name,
+ const std::string &method_name,
+ const std::string &descriptor);
+
tree build_field_reference (tree_builtins *, aot_class *,
tree, model_field *);
+ tree build_field_reference (tree_builtins *builtins,
+ aot_class *current,
+ tree obj,
+ const std::string &classname,
+ const std::string &fieldname,
+ const std::string &descriptor);
+
tree build_class_reference (tree_builtins *, aot_class *,
const std::string &);
@@ -188,9 +216,23 @@
tree build_method_call (tree_builtins *, aot_class *,
tree, tree, model_method *, bool);
+ tree build_method_call (tree_builtins *builtins,
+ aot_class *current,
+ tree obj, tree args,
+ const std::string &class_name,
+ const std::string &method_name,
+ const std::string &descriptor);
+
tree build_field_reference (tree_builtins *, aot_class *,
tree, model_field *);
+ tree build_field_reference (tree_builtins *builtins,
+ aot_class *current,
+ tree obj,
+ const std::string &classname,
+ const std::string &fieldname,
+ const std::string &descriptor);
+
tree build_class_reference (tree_builtins *, aot_class *,
const std::string &);
Index: gcc/java/builtins.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.cc,v
retrieving revision 1.1.2.29
diff -u -r1.1.2.29 builtins.cc
--- gcc/java/builtins.cc 3 Apr 2005 23:50:05 -0000 1.1.2.29
+++ gcc/java/builtins.cc 4 Apr 2005 00:51:16 -0000
@@ -348,12 +348,14 @@
}
tree
-tree_builtins::map_field_ref (aot_class *,
- tree, const std::string &, const std::string &,
- const std::string &)
+tree_builtins::map_field_ref (aot_class *wrapper, tree obj,
+ const std::string &classname,
+ const std::string &fieldname,
+ const std::string &descriptor)
{
- // FIXME
- abort ();
+ gcj_abi *abi = find_abi ();
+ return abi->build_field_reference (this, wrapper, obj, classname,
+ fieldname, descriptor);
}
tree
@@ -395,6 +397,17 @@
}
tree
+tree_builtins::map_method_call (aot_class *wrapper, tree obj, tree args,
+ const std::string &classname,
+ const std::string &meth_name,
+ const std::string &meth_descriptor)
+{
+ gcj_abi *abi = find_abi ();
+ return abi->build_method_call (this, wrapper, obj, args,
+ classname, meth_name, meth_descriptor);
+}
+
+tree
tree_builtins::map_new (aot_class *current, model_class *klass,
model_method *constructor, tree arguments)
{
Index: gcc/java/builtins.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.hh,v
retrieving revision 1.1.2.14
diff -u -r1.1.2.14 builtins.hh
--- gcc/java/builtins.hh 3 Apr 2005 23:50:05 -0000 1.1.2.14
+++ gcc/java/builtins.hh 4 Apr 2005 00:51:16 -0000
@@ -99,6 +99,9 @@
const std::string &);
tree map_method_call (aot_class *, tree, tree, model_method *, bool);
+ tree map_method_call (aot_class *, tree, tree, const std::string &,
+ const std::string &, const std::string &);
+
tree map_new (aot_class *, model_class *, model_method *, tree);
tree map_class_object (model_class *);
Index: gcc/java/lower.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/lower.cc,v
retrieving revision 1.1.2.17
diff -u -r1.1.2.17 lower.cc
--- gcc/java/lower.cc 4 Apr 2005 00:50:33 -0000 1.1.2.17
+++ gcc/java/lower.cc 4 Apr 2005 00:51:19 -0000
@@ -136,10 +136,6 @@
insn = build_empty_stmt ();
break;
- case op_invokevirtual:
- abort ();
- break;
-
case op_aconst_null:
insn = push (null_pointer_node);
break;
@@ -695,13 +691,15 @@
{
tree val2 = pop (type_jfloat);
tree val1 = pop (type_jfloat);
- insn = push (build3 (CALL_EXPR,
- type_jfloat,
- build_address_of (built_in_decls[BUILT_IN_FMODF]),
- tree_cons (NULL_TREE, val1,
- build_tree_list (NULL_TREE,
- val2)),
- NULL_TREE));
+ tree call = build3 (CALL_EXPR,
+ type_jfloat,
+ build_address_of (built_in_decls[BUILT_IN_FMODF]),
+ tree_cons (NULL_TREE, val1,
+ build_tree_list (NULL_TREE,
+ val2)),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
+ insn = push (call);
}
break;
@@ -709,13 +707,15 @@
{
tree val2 = pop (type_jdouble);
tree val1 = pop (type_jdouble);
- insn = push (build3 (CALL_EXPR,
- type_jdouble,
- build_address_of (built_in_decls[BUILT_IN_FMOD]),
- tree_cons (NULL_TREE, val1,
- build_tree_list (NULL_TREE,
- val2)),
- NULL_TREE));
+ tree call = build3 (CALL_EXPR,
+ type_jdouble,
+ build_address_of (built_in_decls[BUILT_IN_FMOD]),
+ tree_cons (NULL_TREE, val1,
+ build_tree_list (NULL_TREE,
+ val2)),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
+ insn = push (call);
}
break;
@@ -1253,16 +1253,62 @@
}
break;
+ case op_invokeinterface:
case op_invokespecial:
- abort ();
- break;
-
case op_invokestatic:
- abort ();
- break;
+ case op_invokevirtual:
+ {
+ jint meth_index = get2u (bytes, pc);
+ std::string classname, methname, descriptor;
+ cpool->get_methodref (meth_index, classname, methname, descriptor);
+ if (op == op_invokeinterface)
+ {
+ // Skip dummy bytes.
+ get2u (bytes, pc);
+ }
- case op_invokeinterface:
- abort ();
+ // FIXME: this method signature parsing code appears in at
+ // least 3 places.
+ tree arg_types = NULL_TREE;
+ for (int i = 0; i < descriptor.length (); ++i)
+ {
+ int start = i;
+ while (descriptor[i] == '[')
+ ++i;
+ if (descriptor[i] == 'L')
+ {
+ while (descriptor[i] != ';')
+ ++i;
+ }
+ // Skip the ';' or, for a primitive type, the sole
+ // character.
+ ++i;
+ std::string tname (&descriptor[start], i - start);
+ // FIXME: BC?
+ tree type = find_class (tname);
+ arg_types = tree_cons (NULL_TREE, type, arg_types);
+ }
+
+ // We want to pop the arguments in reverse order, so we
+ // leave the list of types as we constructed it. After
+ // this loop, we'll have built up the actual arguments in
+ // the correct order.
+ tree arguments = NULL_TREE;
+ for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types))
+ {
+ tree one_type = TREE_VALUE (arg_types);
+ tree one_arg = pop (one_type);
+ arguments = tree_cons (NULL_TREE, one_arg, arguments);
+ }
+
+ tree obj = NULL_TREE;
+ if (op != op_invokestatic)
+ obj = pop (type_object_ptr);
+
+ insn = gcc_builtins->map_method_call (class_wrapper, obj,
+ arguments, classname,
+ methname, descriptor);
+ }
break;
case op_new:
@@ -1277,12 +1323,11 @@
// FIXME: should be ABI call here, as we might want a
// finalizer-free allocator or the like.
tree basetype = TREE_TYPE (TREE_TYPE (builtin_Jv_AllocObject));
- insn = push (convert (type_object_ptr,
- build3 (CALL_EXPR, basetype,
- builtin_Jv_AllocObject,
- build_tree_list (NULL_TREE,
- klass_ref),
- NULL_TREE)));
+ tree call = build3 (CALL_EXPR, basetype, builtin_Jv_AllocObject,
+ build_tree_list (NULL_TREE, klass_ref),
+ NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
+ insn = push (convert (type_object_ptr, call));
}
break;
@@ -1332,6 +1377,7 @@
builtin_Jv_Throw,
build_tree_list (NULL_TREE, value),
NULL_TREE);
+ TREE_SIDE_EFFECTS (insn) = 1;
}
break;
@@ -1345,6 +1391,7 @@
builtin_Jv_CheckCast,
build_tree_list (NULL_TREE, value),
NULL_TREE);
+ TREE_SIDE_EFFECTS (insn) = 1;
}
break;
@@ -1364,6 +1411,7 @@
builtin_Jv_MonitorEnter,
build_tree_list (NULL_TREE, value),
NULL_TREE);
+ TREE_SIDE_EFFECTS (insn) = 1;
}
break;
@@ -1374,6 +1422,7 @@
builtin_Jv_MonitorExit,
build_tree_list (NULL_TREE, value),
NULL_TREE);
+ TREE_SIDE_EFFECTS (insn) = 1;
}
break;
@@ -1410,10 +1459,10 @@
tree klassref = build_class_ref (cpool->get_class (kind_index));
args = tree_cons (NULL_TREE, klassref, args);
- insn = push (build3 (CALL_EXPR, type_object_ptr,
- builtin_Jv_NewMultiArray,
- args,
- NULL_TREE));
+ tree call = build3 (CALL_EXPR, type_object_ptr,
+ builtin_Jv_NewMultiArray, args, NULL_TREE);
+ TREE_SIDE_EFFECTS (call) = 1;
+ insn = push (call);
}
break;