This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: aot-related changes in gcc/java
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 29 Jan 2005 20:16:56 -0700
- Subject: [gcjx] Patch: FYI: aot-related changes in gcc/java
- Reply-to: tromey at redhat dot com
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.