[gcjx] Patch: FYI: aot-related changes in gcc/java

Tom Tromey tromey@redhat.com
Sun Jan 30 03:18:00 GMT 2005


I'm checking this in on the gcjx branch.

This removes the old name mangler and adds some basic support for the
new aot code.  It moves a few methods around, from the builtins to the
tree generator class.  It also updates the class writer a bit to at
least glance in the direction of generating the [oai]table.

This is really just part one of a series of needed cleanups and
restructurings.

Tom

Index: ChangeLog
from  Tom Tromey  <tromey@redhat.com>

	* Make-lang.in (gt-java-mangle.h): Removed.
	(java/mangle.o): Removed.
	* mangle.c: Removed.
	* glue.hh: Include aotclass.hh and aotfactory.hh.
	* lower.cc (visit_bytecode_block): Updated.
	* classobj.hh (class_object_creator::klass): New field.
	(class_object_creator::result): Likewise.
	(class_object_creator): Updated.
	(class_object_creator::get_class): New method.
	* classobj.cc (create_index_table): New method.
	(create_class_instance): Use it.
	* builtins.hh (tree_builtins): Updated.
	* builtins.cc (add): Call SET_DECL_ASSEMBLER_NAME.
	(build_array_reference, build_exception_object_ref,
	build_class_ref, build_divide, build_mod): Removed.
	(check_reference): Likewise.
	* tree.hh (tree_generator::alloc_name_constant): Removed.
	(tree_generator::class_wrapper): New field.
	(tree_generator): Updated.
	* tree.cc (alloc_name_constant): Removed.
	(build_jni_stub): Updated.
	(handle_string_literal): Likewise.
	(build_exception_object_ref): New method.
	(build_class_ref): Likewise.
	(build_divide): Likewise.
	(build_mod): Likewise.
	(build_array_reference): Likewise.
	(check_reference): Likewise.

Index: Make-lang.in
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Make-lang.in,v
retrieving revision 1.151.2.4
diff -u -r1.151.2.4 Make-lang.in
--- Make-lang.in 23 Jan 2005 23:56:06 -0000 1.151.2.4
+++ Make-lang.in 30 Jan 2005 03:14:45 -0000
@@ -74,13 +74,13 @@
 	-rm -f $(GCJ)-cross$(exeext)
 	cp $(GCJ)$(exeext) $(GCJ)-cross$(exeext)
 
-gt-java-hooks.h gt-java-langhooks.h gt-java-mangle.h : s-gtype ; @true
+gt-java-hooks.h gt-java-langhooks.h : s-gtype ; @true
 
 # Executables built by this Makefile:
 JAVA_OBJS = java/abi.o java/builtins.o java/classobj.o java/decl.o \
 java/driver.o java/langhooks.o java/lower.o java/tree.o java/treegen.o
 # later:
-# java/boehm.o java/mangle.o java/mangle_name.o
+# java/boehm.o java/mangle_name.o
 
 JVGENMAIN_OBJS = java/jvgenmain.o java/mangle_name.o errors.o intl.o
 
@@ -232,8 +232,6 @@
   $(TREE_H) toplev.h
 java/jvgenmain.o: java/jvgenmain.c $(CONFIG_H) $(SYSTEM_H) \
   coretypes.h $(TM_H) intl.h
-java/mangle.o: java/mangle.c $(CONFIG_H) $(SYSTEM_H) \
-  coretypes.h $(TM_H) toplev.h $(GGC_H) gt-java-mangle.h
 java/mangle_name.o: java/mangle_name.c $(CONFIG_H) \
   $(SYSTEM_H) coretypes.h $(TM_H) toplev.h $(GGC_H)
 
Index: builtins.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 builtins.cc
--- builtins.cc 23 Jan 2005 01:58:51 -0000 1.1.2.2
+++ builtins.cc 30 Jan 2005 03:14:45 -0000
@@ -23,6 +23,7 @@
 #include "java/glue.hh"
 
 tree_builtins::tree_builtins ()
+  : aot_class_factory ()
 {
 }
 
@@ -114,6 +115,8 @@
 			    mtype);
   TREE_PUBLIC (result) = 1;
   DECL_CONTEXT (result) = context;
+  SET_DECL_ASSEMBLER_NAME (result,
+			   get_identifier (get_mangled_form (meth).c_str ()));
 
   // Convert the actual parameters.  We do this later because we want
   // to set the context when creating the parameter.
@@ -179,6 +182,8 @@
   DECL_CONTEXT (result) = context;
   DECL_EXTERNAL (result) = 1;
   TREE_PUBLIC (result) = 1;
+  SET_DECL_ASSEMBLER_NAME (result,
+			   get_identifier (get_mangled_form (field).c_str ()));
 
   TREE_CHAIN (result) = TYPE_FIELDS (context);
   TYPE_FIELDS (context) = result;
@@ -490,56 +495,6 @@
 }
 
 tree
-tree_builtins::build_array_reference (tree array, tree index, tree result_type,
-				      bool use_checks)
-{
-  tree array_type = TREE_TYPE (array);
-  // Note that the 'data' field is a back-end invention; it does not
-  // exist in the model, so we can't look for it there.
-  tree datafield = find_decl (array_type, "data");
-
-  array = save_expr (array);
-  index = save_expr (index);
-
-  tree current
-    = build4 (ARRAY_REF, result_type,
-	      build3 (COMPONENT_REF, array_type,
-		      build1 (INDIRECT_REF, TREE_TYPE (array_type),
-			      check_reference (array)),
-		      datafield, NULL_TREE),
-	      index,
-	      NULL_TREE, NULL_TREE);
-  TREE_SIDE_EFFECTS (current) = (TREE_SIDE_EFFECTS (array)
-				 || TREE_SIDE_EFFECTS (index));
-
-  if (use_checks && flag_bounds_check)
-    {
-      tree field = find_decl (array_type, "length");
-
-      // First: if ((unsigned) index >= (unsigned) length) throw
-      tree length = build3 (COMPONENT_REF, type_jint,
-			    // Note we don't use check_reference here,
-			    // as we it would be redundant.
-			    build1 (INDIRECT_REF, TREE_TYPE (array_type),
-				    array),
-			    field, NULL_TREE);
-      tree check = build3 (COND_EXPR, void_type_node,
-			   build2 (GE_EXPR, type_jboolean,
-				   build1 (NOP_EXPR, type_juint, index),
-				   build1 (NOP_EXPR, type_juint, length)),
-			   build3 (CALL_EXPR, void_type_node,
-				   builtin_Jv_ThrowBadArrayIndex,
-				   NULL_TREE, NULL_TREE),
-			   build_empty_stmt ());
-      current = build2 (COMPOUND_EXPR, result_type, check, current);
-      TREE_SIDE_EFFECTS (current) = (TREE_SIDE_EFFECTS (array)
-				     || TREE_SIDE_EFFECTS (index));
-    }
-
-  return current;
-}
-
-tree
 tree_builtins::find_decl (tree type, const char *name)
 {
   // This may only be called for local fields.
@@ -551,74 +506,3 @@
     }
   abort ();
 }
-
-// This comes directly from gcj.
-tree
-tree_builtins::build_exception_object_ref (tree type)
-{
-  // Java only passes object via pointer and doesn't require
-  // adjusting.  The java object is immediately before the generic
-  // exception header.
-  tree obj = build0 (EXC_PTR_EXPR, build_pointer_type (type));
-  obj = build2 (MINUS_EXPR, TREE_TYPE (obj), obj,
-		TYPE_SIZE_UNIT (TREE_TYPE (obj)));
-  obj = build1 (INDIRECT_REF, type, obj);
-  return obj;
-}
-
-tree
-tree_builtins::build_class_ref (tree klass)
-{
-  // FIXME.
-  gcj_abi *abi = find_abi (NULL);
-  return abi->build_class_reference (this, klass);
-}
-
-tree
-tree_builtins::build_divide (tree result_type, tree lhs, tree rhs)
-{
-  enum tree_code opcode;
-  if (result_type == type_jfloat || result_type == type_jdouble)
-    opcode = RDIV_EXPR;
-  else
-    {
-      if (flag_use_divide_subroutine)
-	{
-	  tree func;
-	  if (result_type == type_jlong)
-	    func = builtin_Jv_divJ;
-	  else
-	    func = builtin_Jv_divI;
-	  return build3 (CALL_EXPR, result_type, func,
-			 tree_cons (NULL_TREE, lhs,
-				    build_tree_list (NULL_TREE, rhs)),
-			 NULL_TREE);
-	}
-      opcode = TRUNC_DIV_EXPR;
-    }
-
-  return build2 (opcode, result_type, lhs, rhs);
-}
-
-tree
-tree_builtins::build_mod (tree result_type, tree lhs, tree rhs)
-{
-  tree func;
-  if (result_type == type_jfloat || result_type == type_jdouble)
-    func = builtin_fmod;
-  else
-    {
-      if (! flag_use_divide_subroutine)
-	return build2 (TRUNC_MOD_EXPR, result_type, lhs, rhs);
-
-      if (result_type == type_jlong)
-	func = builtin_Jv_remJ;
-      else
-	func = builtin_Jv_remI;
-    }
-
-  return build3 (CALL_EXPR, result_type, func,
-		 tree_cons (NULL_TREE, lhs,
-			    build_tree_list (NULL_TREE, rhs)),
-		 NULL_TREE);
-}
Index: builtins.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.hh,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 builtins.hh
--- builtins.hh 23 Jan 2005 01:58:51 -0000 1.1.2.2
+++ builtins.hh 30 Jan 2005 03:14:45 -0000
@@ -24,7 +24,7 @@
 
 #include "java/abi.hh"
 
-class tree_builtins
+class tree_builtins : public aot_class_factory
 {
   // This maps our types to gcc types.
   std::map<model_type *, tree> typemap;
@@ -82,12 +82,6 @@
     abort ();
   }
 
-  tree build_divide (tree, tree, tree);
-  tree build_mod (tree, tree, tree);
-  tree build_array_reference (tree, tree, tree, bool = true);
-  tree build_exception_object_ref (tree);
-  tree build_class_ref (tree);
-
   tree lay_out_class (model_class *);
 
   tree check_reference (tree);
Index: classobj.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/classobj.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 classobj.cc
--- classobj.cc 23 Jan 2005 01:58:51 -0000 1.1.2.2
+++ classobj.cc 30 Jan 2005 03:14:45 -0000
@@ -97,11 +97,11 @@
 }
 
 tree
-class_object_creator::create_field_array (model_class *klass,
+class_object_creator::create_field_array (model_class *real_class,
 					  int &num_fields,
 					  int &num_static_fields)
 {
-  std::list<ref_field> fields = klass->get_fields ();
+  std::list<ref_field> fields = real_class->get_fields ();
 
   num_fields = 0;
   num_static_fields = 0;
@@ -126,17 +126,52 @@
 }
 
 tree
-class_object_creator::create_method_array (model_class *klass, int &)
+class_object_creator::create_method_array (model_class *real_class, int &)
 {
   return null_pointer_node;	// FIXME
 }
 
 void
-class_object_creator::handle_interfaces (model_class *klass,
+class_object_creator::create_index_table (const std::vector<model_element *> &table,
+					  tree &result_table,
+					  tree &result_syms)
+{
+  for (std::vector<model_element *>::const_iterator i = table.begin ();
+       i != table.end ();
+       ++i)
+    {
+      // We can be looking at a field or a method.
+      // FIXME: it would be nice if we could use IMember; it would
+      // need name and descriptor accessors.
+      std::string class_desc, name, descriptor;
+      if (dynamic_cast<model_field *> (*i))
+	{
+	  model_field *field = assert_cast<model_field *> (*i);
+	  class_desc = field->get_declaring_class ()->get_descriptor ();
+	  name = field->get_name ();
+	  descriptor = field->type ()->get_descriptor ();
+	}
+      else
+	{
+	  model_method *method = assert_cast<model_method *> (*i);
+	  class_desc = method->get_declaring_class ()->get_descriptor ();
+	  name = method->get_name ();
+	  descriptor = method->get_descriptor ();
+	}
+
+      // FIXME: enter new utf8consts.
+      
+    }
+
+  // FIXME create the tables and update the arguments
+}
+
+void
+class_object_creator::handle_interfaces (model_class *real_class,
 					 tree &interfaces,
 					 tree &iface_len)
 {
-  std::list<ref_forwarding_type> ifaces (klass->get_interfaces ());
+  std::list<ref_forwarding_type> ifaces (real_class->get_interfaces ());
   int len = 0;
 
   if (ifaces.empty ())
@@ -170,39 +205,39 @@
 
 }
 
-tree
-class_object_creator::create_class_instance (model_class *klass,
-					     tree class_tree)
+void
+class_object_creator::create_class_instance (tree class_tree)
 {
   assert (TREE_CODE (class_tree) == RECORD_TYPE);
 
   // FIXME: handle fields in Object.
 
-  gcj_abi *abi = builtins->find_abi (klass);
+  model_class *real_class = klass->get ();
+  gcj_abi *abi = builtins->find_abi (real_class);
   record_creator inst (type_class);
 
   inst.set_field ("next", null_pointer_node);
   inst.set_field ("name",
-		  builtins->map_utf8const (klass->get_fully_qualified_name ()));
+		  builtins->map_utf8const (real_class->get_fully_qualified_name ()));
 
-  int mods = klass->get_modifiers ();
+  int mods = real_class->get_modifiers ();
   // Inner classes have modifiers like top-level classes, where the
   // only valid values are public and package-private.
   if ((mods & ACC_ACCESS) != 0 && (mods & ACC_ACCESS) != ACC_PUBLIC)
     mods &= ~ACC_ACCESS;
   inst.set_field ("accflags", build_int_cst (type_jushort, mods));
 
-  model_class *super = klass->get_superclass ();
-  if (klass->interface_p ())
+  model_class *super = real_class->get_superclass ();
+  if (real_class->interface_p ())
     super = global->get_compiler ()->java_lang_Object ();
   inst.set_field ("superclass",
-		  super ? builtins->map_type (klass->get_superclass ())
+		  super ? builtins->map_type (real_class->get_superclass ())
 		  : null_pointer_node);
 
   inst.set_field ("constants", null_pointer_node);  // FIXME
 
   int method_len;
-  tree methods = create_method_array (klass, method_len);
+  tree methods = create_method_array (real_class, method_len);
   inst.set_field ("methods", methods);
   inst.set_field ("method_count", build_int_cst (type_jshort, method_len));
   inst.set_field ("vtable_method_count",
@@ -210,7 +245,8 @@
 				 TREE_VEC_LENGTH (BINFO_VTABLE (TYPE_BINFO (class_tree)))));
 
   int num_fields, num_static_fields;
-  tree field_array = create_field_array (klass, num_fields, num_static_fields);
+  tree field_array = create_field_array (real_class, num_fields,
+					 num_static_fields);
 
   inst.set_field ("fields", field_array);
   inst.set_field ("size_in_bytes", abi->get_size_in_bytes (class_tree));
@@ -221,21 +257,23 @@
   // FIXME abi->get_vtable (blah));
   inst.set_field ("vtable", null_pointer_node);
 
-  tree otable, otable_syms, atable, atable_syms, itable, itable_syms;
-  // FIXME
-//   abi->get_table_info (otable, otable_syms, atable, atable_syms,
-// 		       itable, itable_syms);
-  inst.set_field ("otable", otable);
-  inst.set_field ("otable_syms", otable_syms);
-  inst.set_field ("atable", atable);
-  inst.set_field ("atable_syms", atable_syms);
-  inst.set_field ("itable", itable);
-  inst.set_field ("itable_syms", itable_syms);
+  tree table, syms;
+  create_index_table (klass->get_otable (), table, syms);
+  inst.set_field ("otable", table);
+  inst.set_field ("otable_syms", syms);
+
+  create_index_table (klass->get_atable (), table, syms);
+  inst.set_field ("atable", table);
+  inst.set_field ("atable_syms", syms);
+
+  create_index_table (klass->get_itable (), table, syms);
+  inst.set_field ("itable", table);
+  inst.set_field ("itable_syms", syms);
 
   inst.set_field ("catch_classes", null_pointer_node);  // FIXME
 
   tree interfaces, interface_count;
-  handle_interfaces (klass, interfaces, interface_count);
+  handle_interfaces (real_class, interfaces, interface_count);
   inst.set_field ("interfaces", interfaces);
   inst.set_field ("loader", null_pointer_node);
   inst.set_field ("interface_count", interface_count);
@@ -256,5 +294,5 @@
 
   tree init = inst.finish_record ();
 
-  return make_decl (type_class, init);
+  result = make_decl (type_class, init);
 }
Index: classobj.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/classobj.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 classobj.hh
--- classobj.hh 13 Jan 2005 03:40:26 -0000 1.1.2.1
+++ classobj.hh 30 Jan 2005 03:14:45 -0000
@@ -1,6 +1,6 @@
 // Create a Class instance.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -51,20 +51,36 @@
   // The builtins we use.
   tree_builtins *builtins;
 
+  // The class we're converting.
+  aot_class *klass;
+
+  // The resulting tree.
+  tree result;
+
   tree make_decl (tree, tree);
   tree create_one_field_record (model_field *);
   tree create_field_array (model_class *, int &, int &);
   tree create_method_array (model_class *, int &);
   void handle_interfaces (model_class *, tree &, tree &);
+  void create_index_table (const std::vector<model_element *> &,
+			   tree &, tree &);
+  void create_class_instance (tree);
 
 public:
 
-  class_object_creator (tree_builtins *b)
-    : builtins (b)
+  class_object_creator (tree_builtins *b, aot_class *k)
+    : builtins (b),
+      klass (k)
   {
+    abort ();
+    // create_class_instance (FIXME);
   }
 
-  tree create_class_instance (model_class *, tree);
+  /// Return the class object we created.
+  tree get_class ()
+  {
+    return result;
+  }
 };
 
 #endif // GCC_TREE_CLASSOBJ_HH
Index: glue.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/glue.hh,v
retrieving revision 1.1.2.4
diff -u -r1.1.2.4 glue.hh
--- glue.hh 23 Jan 2005 23:56:06 -0000 1.1.2.4
+++ glue.hh 30 Jan 2005 03:14:45 -0000
@@ -1,6 +1,6 @@
 // Header glue for interfacing with gcc.
 
-// Copyright (C) 2004 Free Software Foundation, Inc.
+// Copyright (C) 2004, 2005 Free Software Foundation, Inc.
 //
 // This file is part of GCC.
 //
@@ -86,6 +86,8 @@
 
 // Now include things from gcjx.
 #include "typedefs.hh"
+#include "aot/aotclass.hh"
+#include "aot/aotfactory.hh"
 #include "java/builtins.hh"
 #include "java/hooks.hh"
 #include "java/classobj.hh"
Index: lower.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/lower.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 lower.cc
--- lower.cc 23 Jan 2005 01:58:51 -0000 1.1.2.2
+++ lower.cc 30 Jan 2005 03:14:45 -0000
@@ -673,7 +673,7 @@
 	  {
 	    tree val2 = pop (type_jint);
 	    tree val1 = pop (type_jint);
-	    insn = push (gcc_builtins->build_divide (type_jint, val1, val2));
+	    insn = push (build_divide (type_jint, val1, val2));
 	  }
 	  break;
 
@@ -681,7 +681,7 @@
 	  {
 	    tree val2 = pop (type_jlong);
 	    tree val1 = pop (type_jlong);
-	    insn = push (gcc_builtins->build_divide (type_jlong, val1, val2));
+	    insn = push (build_divide (type_jlong, val1, val2));
 	  }
 	  break;
 
@@ -701,7 +701,7 @@
 	  {
 	    tree val2 = pop (type_jint);
 	    tree val1 = pop (type_jint);
-	    insn = push (gcc_builtins->build_mod (type_jint, val1, val2));
+	    insn = push (build_mod (type_jint, val1, val2));
 	  }
 	  break;
 
@@ -709,7 +709,7 @@
 	  {
 	    tree val2 = pop (type_jlong);
 	    tree val1 = pop (type_jlong);
-	    insn = push (gcc_builtins->build_mod (type_jlong, val1, val2));
+	    insn = push (build_mod (type_jlong, val1, val2));
 	  }
 	  break;
 
@@ -1327,7 +1327,7 @@
 	    insn = push (build3 (CALL_EXPR, klass,
 				 builtin_Jv_AllocObject,
 				 build_tree_list (NULL_TREE,
-						  gcc_builtins->build_class_ref (klass)),
+						  build_class_ref (klass)),
 				 NULL_TREE));
 	  }
 	  break;
@@ -1807,7 +1807,7 @@
 
   tree index = pop (type_jint);
   tree array = pop (array_type);
-  return gcc_builtins->build_array_reference (array, index, array_type);
+  return build_array_reference (array, index, array_type);
 }
 
 tree
Index: tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.2
diff -u -r1.1.2.2 tree.cc
--- tree.cc 23 Jan 2005 01:58:51 -0000 1.1.2.2
+++ tree.cc 30 Jan 2005 03:14:46 -0000
@@ -229,17 +229,14 @@
   // function pointer.  _Jv_LookupJNIMethod will throw the appropriate
   // exception if this function is not found at runtime.
   tem = build_tree_list (NULL_TREE, build_int_cst (NULL_TREE, args_size));
-  tree method_sig = get_identifier (method->get_descriptor ().c_str ());
-  method_sig
-    = build_ref_from_constant_pool (alloc_name_constant (CONSTANT_Utf8,
-							 method_sig));
+  tree method_sig
+    = build_ref_from_constant_pool (class_wrapper->add_utf (method->get_descriptor ()));
   // FIXME: set TREE_TYPE on method_sig.
   // FIXME: this should probably be done by build_ref_from_constant_pool?
   TREE_CONSTANT (method_sig) = 1;
   tree lookup_arg = tree_cons (NULL_TREE, method_sig, tem);
 
-  tem = build_ref_from_constant_pool (alloc_name_constant (CONSTANT_Utf8,
-							   DECL_NAME (method_tree)));
+  tem = build_ref_from_constant_pool (class_wrapper->add_utf (method->get_name ()));
   lookup_arg
     = tree_cons (NULL_TREE, klass,
 		 tree_cons (NULL_TREE, tem, lookup_arg));
@@ -420,7 +417,7 @@
   tree vtype = gcc_builtins->map_type (vardecl->type ());
   // FIXME: type?
   tree assign = build2 (MODIFY_EXPR, ptr_type_node,
-			var, gcc_builtins->build_exception_object_ref (vtype));
+			var, build_exception_object_ref (vtype));
 
   tsi_link_after (&out, assign, TSI_CONTINUE_LINKING);
 
@@ -899,8 +896,8 @@
       tree idx_tree = build_int_cst (type_jint, index);
       tree assign
 	= build2 (MODIFY_EXPR, elt_tree,
-		  gcc_builtins->build_array_reference (new_expr, idx_tree,
-						       elt_tree, false),
+		  build_array_reference (new_expr, idx_tree,
+					 elt_tree, false),
 		  value);
       TREE_SIDE_EFFECTS (assign) = 1;
       tsi_link_after (&out, assign, TSI_CONTINUE_LINKING);
@@ -924,8 +921,8 @@
   tree component_type
     = gcc_builtins->map_type (array->type ()->element_type ());
 
-  current = gcc_builtins->build_array_reference (array_tree, index_tree,
-						 component_type);
+  current = build_array_reference (array_tree, index_tree,
+				   component_type);
 }
 
 void
@@ -969,8 +966,8 @@
   rhs->visit (this);
   tree rhs_tree = current;
 
-  current = gcc_builtins->build_divide (gcc_builtins->map_type (op->type ()),
-					lhs_tree, rhs_tree);
+  current = build_divide (gcc_builtins->map_type (op->type ()),
+			  lhs_tree, rhs_tree);
   TREE_SIDE_EFFECTS (current) = (TREE_SIDE_EFFECTS (lhs_tree)
 				 | TREE_SIDE_EFFECTS (rhs_tree));
 }
@@ -985,8 +982,8 @@
   rhs->visit (this);
   tree rhs_tree = current;
 
-  current = gcc_builtins->build_mod (gcc_builtins->map_type (op->type ()),
-				     lhs_tree, rhs_tree);
+  current = build_mod (gcc_builtins->map_type (op->type ()),
+		       lhs_tree, rhs_tree);
   TREE_SIDE_EFFECTS (current) = (TREE_SIDE_EFFECTS (lhs_tree)
 				 | TREE_SIDE_EFFECTS (rhs_tree));
 }
@@ -1171,8 +1168,8 @@
 
   current = build2 (MODIFY_EXPR, gcc_builtins->map_type (lhs->type ()),
 		    lhs_tree,
-		    gcc_builtins->build_divide (div_type, lhs_tree,
-						rhs_tree));
+		    build_divide (div_type, lhs_tree,
+				  rhs_tree));
   TREE_SIDE_EFFECTS (current) = 1;
 }
 
@@ -1214,8 +1211,8 @@
 
   current = build2 (MODIFY_EXPR, gcc_builtins->map_type (lhs->type ()),
 		    lhs_tree,
-		    gcc_builtins->build_mod (div_type, lhs_tree,
-					     rhs_tree));
+		    build_mod (div_type, lhs_tree,
+			       rhs_tree));
   TREE_SIDE_EFFECTS (current) = 1;
 }
 
@@ -1310,12 +1307,6 @@
 }
 
 tree
-tree_generator::build_class_ref (tree klass)
-{
-  return gcc_builtins->build_class_ref (klass);
-}
-
-tree
 tree_generator::build_class_ref (model_type *t)
 {
   return build_class_ref (gcc_builtins->map_type (t));
@@ -1569,9 +1560,8 @@
 tree
 tree_generator::handle_string_literal (const std::string &val)
 {
-  tree node = get_identifier (val.c_str ());
-  int location = alloc_name_constant (CONSTANT_String, node);
-  node = build_ref_from_constant_pool (location);
+  int location = class_wrapper->add (val);
+  tree node = build_ref_from_constant_pool (location);
   TREE_TYPE (node)
     = gcc_builtins->map_type (global->get_compiler ()->java_lang_String ());
   TREE_CONSTANT (node) = 1;
@@ -1882,14 +1872,132 @@
   return insn;
 }
 
-int
-tree_generator::alloc_name_constant (classfile_type_constant, tree)
+tree
+tree_generator::build_ref_from_constant_pool (int)
 {
   abort ();			// FIXME
 }
 
+// This comes directly from gcj.
 tree
-tree_generator::build_ref_from_constant_pool (int)
+tree_generator::build_exception_object_ref (tree type)
 {
-  abort ();			// FIXME
+  // Java only passes object via pointer and doesn't require
+  // adjusting.  The java object is immediately before the generic
+  // exception header.
+  tree obj = build0 (EXC_PTR_EXPR, build_pointer_type (type));
+  obj = build2 (MINUS_EXPR, TREE_TYPE (obj), obj,
+		TYPE_SIZE_UNIT (TREE_TYPE (obj)));
+  obj = build1 (INDIRECT_REF, type, obj);
+  return obj;
+}
+
+tree
+tree_generator::build_class_ref (tree klass)
+{
+  // FIXME.
+  gcj_abi *abi = gcc_builtins->find_abi (NULL);
+  // FIXME: this API is wrong, we want to pass in the class wrapper
+  // instead.
+  return abi->build_class_reference (gcc_builtins, klass);
+}
+
+tree
+tree_generator::build_divide (tree result_type, tree lhs, tree rhs)
+{
+  enum tree_code opcode;
+  if (result_type == type_jfloat || result_type == type_jdouble)
+    opcode = RDIV_EXPR;
+  else
+    {
+      if (flag_use_divide_subroutine)
+	{
+	  tree func;
+	  if (result_type == type_jlong)
+	    func = builtin_Jv_divJ;
+	  else
+	    func = builtin_Jv_divI;
+	  return build3 (CALL_EXPR, result_type, func,
+			 tree_cons (NULL_TREE, lhs,
+				    build_tree_list (NULL_TREE, rhs)),
+			 NULL_TREE);
+	}
+      opcode = TRUNC_DIV_EXPR;
+    }
+
+  return build2 (opcode, result_type, lhs, rhs);
+}
+
+tree
+tree_generator::build_mod (tree result_type, tree lhs, tree rhs)
+{
+  tree func;
+  if (result_type == type_jfloat || result_type == type_jdouble)
+    func = builtin_fmod;
+  else
+    {
+      if (! flag_use_divide_subroutine)
+	return build2 (TRUNC_MOD_EXPR, result_type, lhs, rhs);
+
+      if (result_type == type_jlong)
+	func = builtin_Jv_remJ;
+      else
+	func = builtin_Jv_remI;
+    }
+
+  return build3 (CALL_EXPR, result_type, func,
+		 tree_cons (NULL_TREE, lhs,
+			    build_tree_list (NULL_TREE, rhs)),
+		 NULL_TREE);
+}
+
+tree
+tree_generator::build_array_reference (tree array, tree index,
+				       tree result_type,
+				       bool use_checks)
+{
+  tree array_type = TREE_TYPE (array);
+  // Note that the 'data' field is a back-end invention; it does not
+  // exist in the model, so we can't look for it there.
+  tree datafield = gcc_builtins->find_decl (array_type, "data");
+
+  array = save_expr (array);
+  index = save_expr (index);
+
+  tree current
+    = build4 (ARRAY_REF, result_type,
+	      build3 (COMPONENT_REF, array_type,
+		      build1 (INDIRECT_REF, TREE_TYPE (array_type),
+			      gcc_builtins->check_reference (array)),
+		      datafield, NULL_TREE),
+	      index,
+	      NULL_TREE, NULL_TREE);
+  TREE_SIDE_EFFECTS (current) = (TREE_SIDE_EFFECTS (array)
+				 || TREE_SIDE_EFFECTS (index));
+
+  if (use_checks && flag_bounds_check)
+    {
+      tree field = gcc_builtins->find_decl (array_type, "length");
+
+      // First: if ((unsigned) index >= (unsigned) length) throw
+      tree length = build3 (COMPONENT_REF, type_jint,
+			    // Note we don't use check_reference here,
+			    // as we it would be redundant.
+			    build1 (INDIRECT_REF, TREE_TYPE (array_type),
+				    array),
+			    field, NULL_TREE);
+      tree check = build3 (COND_EXPR, void_type_node,
+			   build2 (GE_EXPR, type_jboolean,
+				   build1 (NOP_EXPR, type_juint, index),
+				   build1 (NOP_EXPR, type_juint, length)),
+			   build3 (CALL_EXPR, void_type_node,
+				   builtin_Jv_ThrowBadArrayIndex,
+				   NULL_TREE, NULL_TREE),
+			   build_empty_stmt ());
+      current = build2 (COMPOUND_EXPR, result_type, check, current);
+      TREE_SIDE_EFFECTS (current) = (TREE_SIDE_EFFECTS (array)
+				     || TREE_SIDE_EFFECTS (index));
+    }
+
+  return current;
 }
Index: tree.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.hh,v
retrieving revision 1.1.2.1
diff -u -r1.1.2.1 tree.hh
--- tree.hh 13 Jan 2005 03:40:27 -0000 1.1.2.1
+++ tree.hh 30 Jan 2005 03:14:46 -0000
@@ -31,6 +31,9 @@
   // The underlying compiler we're talking to.
   tree_builtins *gcc_builtins;
 
+  // The wrapper for this method's declaring class.
+  aot_class *class_wrapper;
+
   // This maps statements onto 'break' and 'continue' targets.  The
   // first element of the pair is the 'continue' target, the second
   // element is the 'break' target.
@@ -119,11 +122,14 @@
   tree build_long (jlong);
   tree handle_float (jfloat);
   tree handle_double (jdouble);
-  int alloc_name_constant (classfile_type_constant, tree);
   tree build_ref_from_constant_pool (int);
   tree build_new_array (model_type *, tree);
   tree build_new_object_array (model_type *, tree);
   model_type *find_model_class (const std::string &);
+  tree build_divide (tree, tree, tree);
+  tree build_mod (tree, tree, tree);
+  tree build_array_reference (tree, tree, tree, bool = true);
+  tree build_exception_object_ref (tree);
 
 
   // This class also includes code to transform bytecode to trees.



More information about the Java-patches mailing list