This is the mail archive of the
java-patches@gcc.gnu.org
mailing list for the Java project.
[gcjx] Patch: FYI: grab bag of fixes (last one)
- From: Tom Tromey <tromey at redhat dot com>
- To: Java Patch List <java-patches at gcc dot gnu dot org>
- Date: 08 Mar 2005 19:04:36 -0700
- Subject: [gcjx] Patch: FYI: grab bag of fixes (last one)
- Reply-to: tromey at redhat dot com
I'm checking this in on the gcjx branch.
This is the last gcjx patch from my backlog.
This is a few things that I didn't separate out in my monotone commits
(for no good reason):
- you can't annotate a statement list with a location, as locations
only apply to EXPRs
- use save_expr instead of an explicit temporary for synchronized
(sorry Andrew). I'll change this back later.
- some type fixes
- handle '<primitive type>.class'
With all these patches in place I'm able to get "Hello World" to run.
More complicated things still crash, for instance argument passing
seems to be broken somehow.
Tom
Index: ChangeLog
from Tom Tromey <tromey@redhat.com>
* tree.cc (visit_while): Annotate the loop, not the statements.
* tree.cc (wrap_synchronized): Use save_expr, not a temporary
variable.
* tree.cc (build_new_array): Cast result to correct type.
(build_class_ref): Return result.
* tree.cc (find_field): Rewrote.
* lower.cc (visit_bytecode_block): Updated.
* tree.hh (tree_generator::find_field): Declare.
(tree_generator::build_class_ref): Updated.
(tree_generator::build_new_array): Updated.
* tree.cc (find_field): New method.
(build_class_ref): Handle primitive classes. Added 'request'
argument.
(visit_method): Updated.
(visit_class_ref): Updated.
(visit_instanceof): Updated.
(build_new_array): Updated. Added 'request' argument.
(visit_new_array): Updated.
* builtins.hh (tree_builtins::map_new): Updated.
* tree.cc (visit_new): Pass class_wrapper to map_new.
(visit_cast): Use fold_convert.
(transform_list): Handle case where 'current' is NULL_TREE.
* builtins.cc (map_new): Updated.
(map_new): Added 'current' argument.
* abi.cc (build_new): Changed type of 'klass' argument. Build a
COMPOUND_EXPR.
(build_new): Updated.
* abi.hh (gcj_abi::build_new): Changed type of 'klass' argument.
(cxx_abi::build_new): Updated.
(bc_abi::build_new): Updated.
Index: abi.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.cc,v
retrieving revision 1.1.2.13
diff -u -r1.1.2.13 abi.cc
--- abi.cc 8 Mar 2005 23:02:05 -0000 1.1.2.13
+++ abi.cc 9 Mar 2005 01:55:25 -0000
@@ -181,23 +181,32 @@
tree
cxx_abi::build_new (tree_builtins *builtins, aot_class *current,
- tree klass, tree constructor, tree arguments)
+ model_class *klass, tree constructor, tree arguments)
{
tree allocator = builtin_Jv_AllocObject; // FIXME: finalizer
+ tree klass_tree = builtins->map_type (klass);
// Allocate the object.
- tree n = build3 (CALL_EXPR, klass, allocator,
+ tree n = build3 (CALL_EXPR, TREE_TYPE (TREE_TYPE (allocator)), allocator,
build_tree_list (NULL_TREE,
build_class_reference (builtins, current,
- // FIXME
- NULL)),
+ klass)),
NULL_TREE);
TREE_SIDE_EFFECTS (n) = 1;
+
+ n = build1 (NOP_EXPR, klass_tree, n);
+ TREE_SIDE_EFFECTS (n) = 1;
+
+ tree mem = save_expr (n);
+
// Call the constructor.
- n = build3 (CALL_EXPR, klass, constructor,
- tree_cons (NULL_TREE, n, arguments),
+ n = build3 (CALL_EXPR, void_type_node, build_address_of (constructor),
+ tree_cons (NULL_TREE, mem, arguments),
NULL_TREE);
TREE_SIDE_EFFECTS (n) = 1;
+ n = build2 (COMPOUND_EXPR, klass_tree, n, mem);
+ TREE_SIDE_EFFECTS (n) = 1;
+
return n;
}
@@ -293,7 +302,7 @@
tree
bc_abi::build_new (tree_builtins *builtins, aot_class *current,
- tree klass, tree constructor, tree arguments)
+ model_class *klass, tree constructor, tree arguments)
{
abort ();
}
Index: abi.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/abi.hh,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 abi.hh
--- abi.hh 8 Mar 2005 00:34:36 -0000 1.1.2.6
+++ abi.hh 9 Mar 2005 01:55:26 -0000
@@ -98,7 +98,8 @@
/// its type, constructor, and arguments to the constructor.
virtual tree build_new (tree_builtins *builtins,
aot_class *current,
- tree klass, tree constructor, tree args) = 0;
+ model_class *klass,
+ tree constructor, tree args) = 0;
/// Return an expression representing the size of the class in
/// bytes, or -1 if it can't be known until runtime.
@@ -141,7 +142,7 @@
aot_class *current,
model_type *other);
- tree build_new (tree_builtins *, aot_class *, tree, tree, tree);
+ tree build_new (tree_builtins *, aot_class *, model_class *, tree, tree);
tree get_size_in_bytes (tree klass)
{
@@ -181,7 +182,7 @@
aot_class *current,
model_type *other);
- tree build_new (tree_builtins *, aot_class *, tree, tree, tree);
+ tree build_new (tree_builtins *, aot_class *, model_class *, tree, tree);
tree get_size_in_bytes (tree klass)
{
Index: builtins.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.cc,v
retrieving revision 1.1.2.20
diff -u -r1.1.2.20 builtins.cc
--- builtins.cc 8 Mar 2005 23:02:05 -0000 1.1.2.20
+++ builtins.cc 9 Mar 2005 01:55:26 -0000
@@ -370,11 +370,11 @@
}
tree
-tree_builtins::map_new (model_class *klass, tree constructor, tree arguments)
+tree_builtins::map_new (aot_class *current, model_class *klass,
+ tree constructor, tree arguments)
{
gcj_abi *abi = find_abi ();
- return abi->build_new (this, get_class (klass),
- map_type (klass), constructor, arguments);
+ return abi->build_new (this, current, klass, constructor, arguments);
}
tree
Index: builtins.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/builtins.hh,v
retrieving revision 1.1.2.11
diff -u -r1.1.2.11 builtins.hh
--- builtins.hh 8 Mar 2005 04:04:20 -0000 1.1.2.11
+++ builtins.hh 9 Mar 2005 01:55:26 -0000
@@ -94,7 +94,7 @@
const std::string &);
tree map_method_call (aot_class *, tree, tree, model_method *, bool);
- tree map_new (model_class *, tree, tree);
+ tree map_new (aot_class *, model_class *, tree, tree);
tree map_class_object (model_class *);
/// Memoize a utf8const.
Index: lower.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/lower.cc,v
retrieving revision 1.1.2.6
diff -u -r1.1.2.6 lower.cc
--- lower.cc 8 Mar 2005 01:16:32 -0000 1.1.2.6
+++ lower.cc 9 Mar 2005 01:55:26 -0000
@@ -1335,7 +1335,7 @@
{
model_type *elt_type = vfy_get_primitive_type (get1u (bytes, pc));
tree size = pop (type_jint);
- insn = build_new_array (elt_type, size);
+ insn = build_new_array (elt_type, size, block);
}
break;
Index: tree.cc
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.cc,v
retrieving revision 1.1.2.15
diff -u -r1.1.2.15 tree.cc
--- tree.cc 9 Mar 2005 01:47:12 -0000 1.1.2.15
+++ tree.cc 9 Mar 2005 01:55:26 -0000
@@ -133,7 +133,7 @@
tree k;
if (meth->static_p ())
// FIXME: this is kind of wrong for new ABI code.
- k = build_class_ref (meth->get_declaring_class ());
+ k = build_class_ref (meth->get_declaring_class (), meth);
else
k = this_tree;
current = wrap_synchronized (k, current);
@@ -372,8 +372,10 @@
i != vals.end ();
++i)
{
+ current = NULL_TREE;
(*i)->visit (this);
- tsi_link_after (&out, current, TSI_CONTINUE_LINKING);
+ if (current != NULL_TREE)
+ tsi_link_after (&out, current, TSI_CONTINUE_LINKING);
}
return result;
}
@@ -749,29 +751,20 @@
tree
tree_generator::wrap_synchronized (tree expr, tree body)
{
- // Generate a temporary variable to hold the expression's value.
- char buf[20];
- sprintf (buf, "$synctemp%d", temp_counter);
- ++temp_counter;
-
- tree expr_decl = build_decl (VAR_DECL, get_identifier (buf),
- TREE_TYPE (expr));
- DECL_INITIAL (expr_decl) = current;
- DECL_CONTEXT (expr_decl) = method_tree;
- TREE_CHAIN (expr_decl) = BLOCK_VARS (current_block);
- BLOCK_VARS (current_block) = expr_decl;
+ // Make sure we only evaluate the expression once.
+ expr = save_expr (expr);
// Emit a call to enter the monitor.
tree enter = build3 (CALL_EXPR, void_type_node,
builtin_Jv_MonitorEnter,
- build_tree_list (NULL_TREE, expr_decl),
+ build_tree_list (NULL_TREE, expr),
NULL_TREE);
TREE_SIDE_EFFECTS (enter) = 1;
// Build a call to leave the monitor, we use it shortly.
tree exit_tree = build3 (CALL_EXPR, void_type_node,
builtin_Jv_MonitorExit,
- build_tree_list (NULL_TREE, expr_decl),
+ build_tree_list (NULL_TREE, expr),
NULL_TREE);
TREE_SIDE_EFFECTS (exit_tree) = 1;
@@ -899,14 +892,13 @@
// Now wrap the body in a loop, and add the "done" label.
body_tree = build1 (LOOP_EXPR, void_type_node, body_tree);
+ annotate (body_tree, wstmt);
current = alloc_stmt_list ();
out = tsi_start (current);
tsi_link_after (&out, body_tree, TSI_CONTINUE_LINKING);
tsi_link_after (&out, build1 (LABEL_EXPR, void_type_node, done),
TSI_CONTINUE_LINKING);
-
- annotate (current, wstmt);
}
@@ -1325,8 +1317,8 @@
if (dest->type ()->primitive_p ())
{
- current = build1 (CONVERT_EXPR, gcc_builtins->map_type (dest->type ()),
- expr_tree);
+ current = fold_convert (gcc_builtins->map_type (dest->type ()),
+ expr_tree);
TREE_SIDE_EFFECTS (current) = TREE_SIDE_EFFECTS (expr_tree);
}
else
@@ -1352,10 +1344,10 @@
}
void
-tree_generator::visit_class_ref (model_class_ref *,
+tree_generator::visit_class_ref (model_class_ref *ref,
const ref_forwarding_type &req)
{
- current = build_class_ref (req->type ());
+ current = build_class_ref (req->type (), ref);
}
void
@@ -1508,13 +1500,13 @@
}
void
-tree_generator::visit_instanceof (model_instanceof *,
+tree_generator::visit_instanceof (model_instanceof *stmt,
const ref_expression &expr,
const ref_forwarding_type &klass)
{
expr->visit (this);
tree expr_tree = save_expr (current);
- tree class_tree = build_class_ref (klass->type ());
+ tree class_tree = build_class_ref (klass->type (), stmt);
current = handle_instanceof (expr_tree, class_tree);
}
@@ -1735,7 +1727,7 @@
model_class *klassp = assert_cast<model_class *> (klass->type ());
gcc_builtins->lay_out_class (klassp);
current
- = gcc_builtins->map_new (klassp,
+ = gcc_builtins->map_new (class_wrapper, klassp,
gcc_builtins->map_method (const_cast<model_method *>(constructor)),
arg_tree);
}
@@ -1753,7 +1745,7 @@
tree ind_tree = current;
if (elt_type->type ()->primitive_p ())
- current = build_new_array (elt_type->type (), ind_tree);
+ current = build_new_array (elt_type->type (), ind_tree, new_elt);
else
current = build_new_object_array (elt_type->type (), ind_tree);
}
@@ -1893,21 +1885,27 @@
}
tree
-tree_generator::build_new_array (model_type *elt_type, tree size)
+tree_generator::build_new_array (model_type *elt_type, tree size,
+ model_element *request)
{
assert (elt_type->primitive_p ());
model_type *array_type = elt_type->array ();
tree array_type_tree = gcc_builtins->map_type (array_type);
- tree insn = build3 (CALL_EXPR, array_type_tree,
+ tree insn = build3 (CALL_EXPR,
+ TREE_TYPE (TREE_TYPE (builtin_Jv_NewPrimArray)),
builtin_Jv_NewPrimArray,
tree_cons (NULL_TREE,
- build_class_ref (elt_type),
+ build_class_ref (elt_type, request),
tree_cons (NULL_TREE, size, NULL_TREE)),
NULL_TREE);
TREE_SIDE_EFFECTS (insn) = 1;
+ // Now cast to correct type.
+ insn = build1 (NOP_EXPR, array_type_tree, insn);
+ TREE_SIDE_EFFECTS (insn) = 1;
+
return insn;
}
@@ -1956,13 +1954,49 @@
return obj;
}
+// FIXME: this is (sort of) duplicated in bytecode_generator.
+model_field *
+tree_generator::find_field (const std::string &name,
+ model_class *klass, model_type *type,
+ model_element *request)
+{
+ std::set<model_field *> result;
+ klass->find_members (name, result, klass, NULL);
+ if (result.size () == 1)
+ {
+ model_field *field = *(result.begin ());
+ if (field->type () == type)
+ return field;
+ }
+ throw request->error ("couldn't find field %1 of type %2 in class %3")
+ % name % type % klass;
+}
+
tree
-tree_generator::build_class_ref (model_type *t)
+tree_generator::build_class_ref (model_type *t, model_element *request)
{
- gcj_abi *abi = gcc_builtins->find_abi ();
- // FIXME: we can see "int.class".
- return abi->build_class_reference (gcc_builtins, class_wrapper,
- assert_cast<model_class *> (t));
+ tree result;
+
+ assert (t != null_type);
+ if (t->primitive_p () || t == primitive_void_type)
+ {
+ model_class *wrapper = box_primitive_type (t);
+ // Maybe for BC we could still emit a direct reference to the
+ // primitive class?
+ model_field *field
+ = find_field ("TYPE", wrapper,
+ global->get_compiler ()->java_lang_Class (),
+ request);
+ result = gcc_builtins->map_field_ref (class_wrapper, NULL_TREE,
+ field);
+ }
+ else
+ {
+ gcj_abi *abi = gcc_builtins->find_abi ();
+ result = abi->build_class_reference (gcc_builtins, class_wrapper,
+ assert_cast<model_class *> (t));
+ }
+ return result;
}
tree
Index: tree.hh
===================================================================
RCS file: /cvs/gcc/gcc/gcc/java/Attic/tree.hh,v
retrieving revision 1.1.2.5
diff -u -r1.1.2.5 tree.hh
--- tree.hh 8 Mar 2005 01:22:00 -0000 1.1.2.5
+++ tree.hh 9 Mar 2005 01:55:27 -0000
@@ -103,7 +103,7 @@
void annotate (tree, model_element *);
tree wrap_synchronized (tree, tree);
tree add_var (const ref_variable_decl &);
- tree build_class_ref (model_type *);
+ tree build_class_ref (model_type *, model_element *);
tree build_class_ref (const std::string &);
tree handle_instanceof (tree, tree);
void handle_inc_dec (tree_code, const ref_expression &);
@@ -123,7 +123,7 @@
tree handle_float (jfloat);
tree handle_double (jdouble);
tree build_ref_from_constant_pool (tree, int);
- tree build_new_array (model_type *, tree);
+ tree build_new_array (model_type *, tree, model_element *);
tree build_new_object_array (model_type *, tree);
model_type *find_model_class (const std::string &);
tree build_divide (tree, tree, tree);
@@ -157,6 +157,9 @@
tree find_class (const std::string &);
tree handle_ldc (constant_pool *, uint16);
bool type_wide_p (tree) const;
+ model_field *find_field (const std::string &name,
+ model_class *klass, model_type *type,
+ model_element *request);
public: