[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