summaryrefslogtreecommitdiff
path: root/gcc/java/jcf-write.c
diff options
context:
space:
mode:
authorbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>2001-03-24 01:13:30 +0000
committerbothner <bothner@138bc75d-0d04-0410-961f-82ee72b054a4>2001-03-24 01:13:30 +0000
commite722e1a88538456e8f42aab2414d0fd49e218df2 (patch)
treeb1eef7b31ca3d14d2d241bc45c3318313375f660 /gcc/java/jcf-write.c
parent85dee3e86c19116d1129c6d556cbbd6231c1d252 (diff)
downloadgcc-e722e1a88538456e8f42aab2414d0fd49e218df2.tar.gz
e
* verify.c (verify_jvm_instructions): Replace 3 pop_type by POP_TYPE macro for better error pin-pointing. * java-tree.h: Fix typo in comment. * jcf-write.c (generate_bytecode_insns): Changes to TRY_FINALLY_EXPR. Don't include jsr/goto in exception range. Check if start and end of exception range are the same (also TRY_EXPR). Don't emit jsr after try_block if CAN_COMPLETE_NORMALLY is false. However, do emit the following goto even if try_block is empty. Defer freeing exception_decl until after the finalizer, to make sure the local isn't reused in the finalizer. Fixes PR java/1208. * parse.y (java_complete_lhs): If the try-clause is empty, just return the finally-clause and vice versa. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@40801 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/java/jcf-write.c')
-rw-r--r--gcc/java/jcf-write.c78
1 files changed, 36 insertions, 42 deletions
diff --git a/gcc/java/jcf-write.c b/gcc/java/jcf-write.c
index 46f73fe9cbb..4593e8a64b5 100644
--- a/gcc/java/jcf-write.c
+++ b/gcc/java/jcf-write.c
@@ -111,7 +111,7 @@ struct chunk
struct jcf_block
{
/* For blocks that that are defined, the next block (in pc order).
- For blocks that are the not-yet-defined end label of a LABELED_BLOCK_EXPR
+ For blocks that are not-yet-defined the end label of a LABELED_BLOCK_EXPR
or a cleanup expression (from a WITH_CLEANUP_EXPR),
this is the next (outer) such end label, in a stack headed by
labeled_blocks in jcf_partial. */
@@ -131,8 +131,8 @@ struct jcf_block
int linenumber;
- /* After finish_jcf_block is called, The actual instructions
- contained in this block. Before than NULL, and the instructions
+ /* After finish_jcf_block is called, the actual instructions
+ contained in this block. Before that NULL, and the instructions
are in state->bytecode. */
union {
struct chunk *chunk;
@@ -2311,6 +2311,8 @@ generate_bytecode_insns (exp, target, state)
abort ();
generate_bytecode_insns (try_clause, IGNORE_TARGET, state);
end_label = get_jcf_label_here (state);
+ if (end_label == start_label)
+ break;
if (CAN_COMPLETE_NORMALLY (try_clause))
emit_goto (finished_label, state);
while (clause != NULL_TREE)
@@ -2332,61 +2334,53 @@ generate_bytecode_insns (exp, target, state)
break;
case TRY_FINALLY_EXPR:
{
- struct jcf_block *finished_label, *finally_label, *start_label;
+ struct jcf_block *finished_label,
+ *finally_label, *start_label, *end_label;
struct jcf_handler *handler;
- int worthwhile_finally = 1;
tree try_block = TREE_OPERAND (exp, 0);
tree finally = TREE_OPERAND (exp, 1);
- tree return_link, exception_decl;
+ tree return_link = NULL_TREE, exception_decl = NULL_TREE;
- finally_label = start_label = NULL;
- return_link = exception_decl = NULL_TREE;
- finished_label = gen_jcf_label (state);
+ tree exception_type;
- /* If the finally clause happens to be empty, set a flag so we
- remember to just skip it. */
- if (BLOCK_EXPR_BODY (finally) == empty_stmt_node)
- worthwhile_finally = 0;
+ finally_label = gen_jcf_label (state);
+ start_label = get_jcf_label_here (state);
+ finally_label->pc = PENDING_CLEANUP_PC;
+ finally_label->next = state->labeled_blocks;
+ state->labeled_blocks = finally_label;
+ state->num_finalizers++;
+
+ generate_bytecode_insns (try_block, target, state);
+ if (state->labeled_blocks != finally_label)
+ abort();
+ state->labeled_blocks = finally_label->next;
+ end_label = get_jcf_label_here (state);
- if (worthwhile_finally)
+ if (end_label == start_label)
{
- tree exception_type;
- return_link = build_decl (VAR_DECL, NULL_TREE,
- return_address_type_node);
- exception_type = build_pointer_type (throwable_type_node);
- exception_decl = build_decl (VAR_DECL, NULL_TREE, exception_type);
-
- finally_label = gen_jcf_label (state);
- start_label = get_jcf_label_here (state);
- finally_label->pc = PENDING_CLEANUP_PC;
- finally_label->next = state->labeled_blocks;
- state->labeled_blocks = finally_label;
- state->num_finalizers++;
+ state->num_finalizers--;
+ define_jcf_label (finally_label, state);
+ generate_bytecode_insns (finally, IGNORE_TARGET, state);
+ break;
}
- generate_bytecode_insns (try_block, target, state);
+ return_link = build_decl (VAR_DECL, NULL_TREE,
+ return_address_type_node);
+ finished_label = gen_jcf_label (state);
- if (worthwhile_finally)
+
+ if (CAN_COMPLETE_NORMALLY (try_block))
{
- if (state->labeled_blocks != finally_label)
- abort();
- state->labeled_blocks = finally_label->next;
emit_jsr (finally_label, state);
+ emit_goto (finished_label, state);
}
- if (CAN_COMPLETE_NORMALLY (try_block)
- && TREE_CODE (try_block) == BLOCK
- && BLOCK_EXPR_BODY (try_block) != empty_stmt_node)
- emit_goto (finished_label, state);
-
/* Handle exceptions. */
- if (!worthwhile_finally)
- break;
-
+ exception_type = build_pointer_type (throwable_type_node);
+ exception_decl = build_decl (VAR_DECL, NULL_TREE, exception_type);
localvar_alloc (return_link, state);
- handler = alloc_handler (start_label, NULL_PTR, state);
- handler->end_label = handler->handler_label;
+ handler = alloc_handler (start_label, end_label, state);
handler->type = NULL_TREE;
localvar_alloc (exception_decl, state);
NOTE_PUSH (1);
@@ -2396,7 +2390,6 @@ generate_bytecode_insns (exp, target, state)
RESERVE (1);
OP1 (OPCODE_athrow);
NOTE_POP (1);
- localvar_free (exception_decl, state);
/* The finally block. First save return PC into return_link. */
define_jcf_label (finally_label, state);
@@ -2405,6 +2398,7 @@ generate_bytecode_insns (exp, target, state)
generate_bytecode_insns (finally, IGNORE_TARGET, state);
maybe_wide (OPCODE_ret, DECL_LOCAL_INDEX (return_link), state);
+ localvar_free (exception_decl, state);
localvar_free (return_link, state);
define_jcf_label (finished_label, state);
}