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]
Other format: [Raw text]

[gcjx] Patch: FYI: handle invoke_* opcodes


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;
 


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