Commit ba60e475 by Andrew Haley Committed by Andrew Haley

except.c (expand_start_java_handler): Push a new binding level.

2004-06-29  Andrew Haley  <aph@redhat.com>

        * except.c (expand_start_java_handler): Push a new binding level.
        Don't build a TRY_CATCH_EXPR now, we'll do it later.  Call
        register_exception_range() to register where we'll do it.
        (expand_end_java_handler): Remove old bogus code.  Replace with
        new logic that simply builds TRY_CATCH_EXPRs and inserts them at
        the top of the expression we're curently building.
        (maybe_end_try): Delete.
        * decl.c (binding_level.exception_range): New field.
        (clear_binding_level): Add field exception_range.  Reformat.
        (poplevel): Call expand_end_java_handler().
        (poplevel): Call java_add_stmt only if functionbody is false.
        (maybe_poplevels): Don't call maybe_end_try() from here.
        (end_java_method): Clear no longer used trees in function decl.
        (register_exception_range): New function.
        * java-tree.h (register_exception_range, struct eh_range): Declare.

From-SVN: r83857
parent 9f6eb0f4
2004-06-29 Andrew Haley <aph@redhat.com>
* except.c (expand_start_java_handler): Push a new binding level.
Don't build a TRY_CATCH_EXPR now, we'll do it later. Call
register_exception_range() to register where we'll do it.
(expand_end_java_handler): Remove old bogus code. Replace with
new logic that simply builds TRY_CATCH_EXPRs and inserts them at
the top of the expression we're curently building.
(maybe_end_try): Delete.
* decl.c (binding_level.exception_range): New field.
(clear_binding_level): Add field exception_range. Reformat.
(poplevel): Call expand_end_java_handler().
(poplevel): Call java_add_stmt only if functionbody is false.
(maybe_poplevels): Don't call maybe_end_try() from here.
(end_java_method): Clear no longer used trees in function decl.
(register_exception_range): New function.
* java-tree.h (register_exception_range, struct eh_range): Declare.
2004-06-28 Bryce McKinlay <mckinlay@redhat.com> 2004-06-28 Bryce McKinlay <mckinlay@redhat.com>
* jcf-write.c (get_classfile_modifiers): Formatting fixes. * jcf-write.c (get_classfile_modifiers): Formatting fixes.
......
...@@ -314,6 +314,9 @@ struct binding_level GTY(()) ...@@ -314,6 +314,9 @@ struct binding_level GTY(())
/* The statements in this binding level. */ /* The statements in this binding level. */
tree stmts; tree stmts;
/* An exception range associated with this binding level. */
struct eh_range * GTY((skip (""))) exception_range;
/* Binding depth at which this level began. Used only for debugging. */ /* Binding depth at which this level began. Used only for debugging. */
unsigned binding_depth; unsigned binding_depth;
}; };
...@@ -341,8 +344,18 @@ static GTY(()) struct binding_level *global_binding_level; ...@@ -341,8 +344,18 @@ static GTY(()) struct binding_level *global_binding_level;
/* Binding level structures are initialized by copying this one. */ /* Binding level structures are initialized by copying this one. */
static const struct binding_level clear_binding_level static const struct binding_level clear_binding_level
= {NULL_TREE, NULL_TREE, NULL_TREE, NULL_TREE, = {
NULL_BINDING_LEVEL, LARGEST_PC, 0, NULL_TREE, 0}; NULL_TREE, /* names */
NULL_TREE, /* shadowed */
NULL_TREE, /* blocks */
NULL_TREE, /* this_lock */
NULL_BINDING_LEVEL, /* level_chain */
LARGEST_PC, /* end_pc */
0, /* start_pc */
NULL, /* stmts */
NULL, /* exception_range */
0, /* binding_depth */
};
#if 0 #if 0
/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function /* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function
...@@ -1316,6 +1329,9 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -1316,6 +1329,9 @@ poplevel (int keep, int reverse, int functionbody)
TREE_TYPE (block) = void_type_node; TREE_TYPE (block) = void_type_node;
} }
if (current_binding_level->exception_range)
expand_end_java_handler (current_binding_level->exception_range);
if (block != 0) if (block != 0)
{ {
/* If any statements have been generated at this level, create a /* If any statements have been generated at this level, create a
...@@ -1341,7 +1357,6 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -1341,7 +1357,6 @@ poplevel (int keep, int reverse, int functionbody)
bind = build (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block), bind = build (BIND_EXPR, TREE_TYPE (block), BLOCK_VARS (block),
BLOCK_EXPR_BODY (block), block); BLOCK_EXPR_BODY (block), block);
BIND_EXPR_BODY (bind) = current_binding_level->stmts; BIND_EXPR_BODY (bind) = current_binding_level->stmts;
if (BIND_EXPR_BODY (bind) if (BIND_EXPR_BODY (bind)
...@@ -1448,7 +1463,9 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -1448,7 +1463,9 @@ poplevel (int keep, int reverse, int functionbody)
DECL_INITIAL (current_function_decl) = block; DECL_INITIAL (current_function_decl) = block;
DECL_SAVED_TREE (current_function_decl) = bind; DECL_SAVED_TREE (current_function_decl) = bind;
} }
else if (block) else
{
if (block)
{ {
if (!block_previously_created) if (!block_previously_created)
current_binding_level->blocks current_binding_level->blocks
...@@ -1465,6 +1482,7 @@ poplevel (int keep, int reverse, int functionbody) ...@@ -1465,6 +1482,7 @@ poplevel (int keep, int reverse, int functionbody)
if (bind) if (bind)
java_add_stmt (bind); java_add_stmt (bind);
}
if (block) if (block)
TREE_USED (block) = 1; TREE_USED (block) = 1;
...@@ -1521,11 +1539,7 @@ maybe_poplevels (int pc) ...@@ -1521,11 +1539,7 @@ maybe_poplevels (int pc)
#endif #endif
while (current_binding_level->end_pc <= pc) while (current_binding_level->end_pc <= pc)
{
maybe_end_try (current_binding_level->start_pc, pc);
poplevel (1, 0, 0); poplevel (1, 0, 0);
}
maybe_end_try (0, pc);
} }
/* Terminate any binding which began during the range beginning at /* Terminate any binding which began during the range beginning at
...@@ -1781,6 +1795,14 @@ end_java_method (void) ...@@ -1781,6 +1795,14 @@ end_java_method (void)
flag_unit_at_a_time = 0; flag_unit_at_a_time = 0;
finish_method (fndecl); finish_method (fndecl);
if (! flag_unit_at_a_time)
{
/* Nulling these fields when we no longer need them saves
memory. */
DECL_SAVED_TREE (fndecl) = NULL;
DECL_STRUCT_FUNCTION (fndecl) = NULL;
DECL_INITIAL (fndecl) = NULL_TREE;
}
current_function_decl = NULL_TREE; current_function_decl = NULL_TREE;
} }
...@@ -1929,5 +1951,19 @@ get_stmts (void) ...@@ -1929,5 +1951,19 @@ get_stmts (void)
return &current_binding_level->stmts; return &current_binding_level->stmts;
} }
/* Register an exception range as belonging to the current binding
level. There may only be one: if there are more, we'll create more
binding levels. However, each range can have multiple handlers,
and these are expanded when we call expand_end_java_handler(). */
void
register_exception_range (struct eh_range *range, int pc, int end_pc)
{
if (current_binding_level->exception_range)
abort ();
current_binding_level->exception_range = range;
current_binding_level->end_pc = end_pc;
current_binding_level->start_pc = pc;
}
#include "gt-java-decl.h" #include "gt-java-decl.h"
...@@ -40,7 +40,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */ ...@@ -40,7 +40,6 @@ The Free Software Foundation is independent of Sun Microsystems, Inc. */
#include "toplev.h" #include "toplev.h"
static void expand_start_java_handler (struct eh_range *); static void expand_start_java_handler (struct eh_range *);
static void expand_end_java_handler (struct eh_range *);
static struct eh_range *find_handler_in_range (int, struct eh_range *, static struct eh_range *find_handler_in_range (int, struct eh_range *,
struct eh_range *); struct eh_range *);
static void link_handler (struct eh_range *, struct eh_range *); static void link_handler (struct eh_range *, struct eh_range *);
...@@ -305,13 +304,8 @@ expand_start_java_handler (struct eh_range *range) ...@@ -305,13 +304,8 @@ expand_start_java_handler (struct eh_range *range)
fprintf (stderr, "expand start handler pc %d --> %d\n", fprintf (stderr, "expand start handler pc %d --> %d\n",
current_pc, range->end_pc); current_pc, range->end_pc);
#endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */ #endif /* defined(DEBUG_JAVA_BINDING_LEVELS) */
{ pushlevel (0);
tree new = build (TRY_CATCH_EXPR, void_type_node, NULL, NULL); register_exception_range (range, range->start_pc, range->end_pc);
TREE_SIDE_EFFECTS (new) = 1;
java_add_stmt (build_java_empty_stmt ());
range->stmt = java_add_stmt (new);
}
range->expanded = 1; range->expanded = 1;
} }
...@@ -428,13 +422,11 @@ build_exception_object_ref (tree type) ...@@ -428,13 +422,11 @@ build_exception_object_ref (tree type)
/* If there are any handlers for this range, isssue end of range, /* If there are any handlers for this range, isssue end of range,
and then all handler blocks */ and then all handler blocks */
static void void
expand_end_java_handler (struct eh_range *range) expand_end_java_handler (struct eh_range *range)
{ {
tree handler = range->handlers; tree handler = range->handlers;
tree compound = NULL;
force_poplevels (range->start_pc);
for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler)) for ( ; handler != NULL_TREE; handler = TREE_CHAIN (handler))
{ {
/* For bytecode we treat exceptions a little unusually. A /* For bytecode we treat exceptions a little unusually. A
...@@ -444,54 +436,17 @@ expand_end_java_handler (struct eh_range *range) ...@@ -444,54 +436,17 @@ expand_end_java_handler (struct eh_range *range)
extra (and difficult) work to get this to look like a extra (and difficult) work to get this to look like a
gcc-style finally clause. */ gcc-style finally clause. */
tree type = TREE_PURPOSE (handler); tree type = TREE_PURPOSE (handler);
if (type == NULL) if (type == NULL)
type = throwable_type_node; type = throwable_type_node;
type = prepare_eh_table_type (type); type = prepare_eh_table_type (type);
if (compound)
{ {
/* If we already have a COMPOUND there is more than one
catch handler for this try block. Wrap the
TRY_CATCH_EXPR in operand 1 of COMPOUND with another
TRY_CATCH_EXPR. */
tree inner_try_expr = TREE_OPERAND (compound, 1);
tree catch_expr tree catch_expr
= build (CATCH_EXPR, void_type_node, type, = build (CATCH_EXPR, void_type_node, type,
build (GOTO_EXPR, void_type_node, TREE_VALUE (handler))); build (GOTO_EXPR, void_type_node, TREE_VALUE (handler)));
tree try_expr tree try_catch_expr = build (TRY_CATCH_EXPR, void_type_node,
= build (TRY_CATCH_EXPR, void_type_node, *get_stmts (), catch_expr);
inner_try_expr, catch_expr); *get_stmts () = try_catch_expr;
TREE_OPERAND (compound, 1) = try_expr;
}
else
{
tree *stmts = get_stmts ();
tree outer;
tree try_expr;
compound = range->stmt;
outer = TREE_OPERAND (compound, 0);
try_expr = TREE_OPERAND (compound, 1);
/* On the left of COMPOUND is the expresion to be evaluated
before the try handler is entered; on the right is a
TRY_FINALLY_EXPR with no operands as yet. In the current
statement list is an expression that we're going to move
inside the try handler. We'll create a new COMPOUND_EXPR
with the outer context on the left and the TRY_FINALLY_EXPR
on the right, then nullify both operands of COMPOUND, which
becomes the final expression in OUTER. This new compound
expression replaces the current statement list. */
TREE_OPERAND (try_expr, 0) = *stmts;
TREE_OPERAND (try_expr, 1)
= build (CATCH_EXPR, void_type_node, type,
build (GOTO_EXPR, void_type_node, TREE_VALUE (handler)));
TREE_SIDE_EFFECTS (try_expr) = 1;
TREE_OPERAND (compound, 0) = build_java_empty_stmt ();
TREE_OPERAND (compound, 1) = build_java_empty_stmt ();
compound
= build (COMPOUND_EXPR, TREE_TYPE (try_expr), outer, try_expr);
*stmts = compound;
} }
} }
#if defined(DEBUG_JAVA_BINDING_LEVELS) #if defined(DEBUG_JAVA_BINDING_LEVELS)
...@@ -536,19 +491,3 @@ maybe_start_try (int start_pc, int end_pc) ...@@ -536,19 +491,3 @@ maybe_start_try (int start_pc, int end_pc)
check_start_handlers (range, start_pc); check_start_handlers (range, start_pc);
} }
/* Emit any end-of-try-range ending at end_pc and starting before
start_pc. */
void
maybe_end_try (int start_pc, int end_pc)
{
if (! doing_eh (1))
return;
while (current_range != NULL_EH_RANGE && current_range->end_pc <= end_pc
&& current_range->start_pc >= start_pc)
{
expand_end_java_handler (current_range);
current_range = current_range->outer;
}
}
...@@ -68,3 +68,4 @@ extern void maybe_end_try (int, int); ...@@ -68,3 +68,4 @@ extern void maybe_end_try (int, int);
extern void add_handler (int, int, tree, tree); extern void add_handler (int, int, tree, tree);
extern void handle_nested_ranges (void); extern void handle_nested_ranges (void);
extern void expand_resume_after_catch (void); extern void expand_resume_after_catch (void);
extern void expand_end_java_handler (struct eh_range *);
...@@ -1117,6 +1117,9 @@ struct lang_type GTY(()) ...@@ -1117,6 +1117,9 @@ struct lang_type GTY(())
#define SEARCH_SUPER 2 #define SEARCH_SUPER 2
#define SEARCH_VISIBLE 4 #define SEARCH_VISIBLE 4
/* Defined in java-except.h */
struct eh_range;
extern void java_parse_file (int); extern void java_parse_file (int);
extern bool java_mark_addressable (tree); extern bool java_mark_addressable (tree);
extern tree java_type_for_mode (enum machine_mode, int); extern tree java_type_for_mode (enum machine_mode, int);
...@@ -1345,6 +1348,7 @@ extern tree add_stmt_to_compound (tree, tree, tree); ...@@ -1345,6 +1348,7 @@ extern tree add_stmt_to_compound (tree, tree, tree);
extern tree java_add_stmt (tree); extern tree java_add_stmt (tree);
extern tree java_add_local_var (tree decl); extern tree java_add_local_var (tree decl);
extern tree *get_stmts (void); extern tree *get_stmts (void);
extern void register_exception_range(struct eh_range *, int, int);
extern void finish_method (tree); extern void finish_method (tree);
extern void java_expand_body (tree); extern void java_expand_body (tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment