expr.c (process_jvm_instruction): Do load_type_state after JSR.
d * expr.c (process_jvm_instruction): Do load_type_state after JSR. * verify.c (verify_jvm_instructions): Fix off-by-one error. * jcf-write.c (CHECK_PUT): Add (void) cast to avoid -Wall warnings. (localvar_alloc): Change return type to void, (emit_unop): Remove unused variable size. * jcf-write.c (struct jcf_block): Add new union. (PENDING_CLEANUP_PC, PENDING_EXIT_PC, UNDEFINED_PC): New macros. (call_cleanups): New functions. (struct jcf_partial): New fields num_finalizers and return_value_decl. (generate_bytecode_insns): Support CLEANUP_POINT_EXPR and WITH_CLEANUP_EXPR. Handle cleanups in RETURN_EXPR and EXIT_BLOCK_EXPR. * lang.c (lang_init): Call using_eh_for_cleanups. * parse.y (java_complete_lhs): For SYNCHRONIZED_EXPR, defer completing operands to patch_synchronized_statement. Support CLEANUP_POINT_EXPR, WITH_CLEANUP_EXPR. (patch_synchronized_statement): Re-write suing CLEANUP_POINT_EXPR and WITH_CLEANUP_EXPR instead of TRY_EXPR. From-SVN: r24406
This commit is contained in:
parent
e402ca989b
commit
5a005d9ead
@ -2191,6 +2191,7 @@ process_jvm_instruction (PC, byte_ops, length)
|
||||
tree where = lookup_label (oldpc+OPERAND_VALUE); \
|
||||
tree ret = lookup_label (PC); \
|
||||
build_java_jsr (where, ret); \
|
||||
load_type_state (ret); \
|
||||
}
|
||||
|
||||
/* Push a constant onto the stack. */
|
||||
|
@ -2272,7 +2272,7 @@ static const short yycheck[] = { 3,
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
|
||||
|
||||
/* As a special exception, when this file is copied by Bison into a
|
||||
Bison output file, you may use that output file without restriction.
|
||||
@ -10129,13 +10129,24 @@ java_complete_lhs (node)
|
||||
|
||||
case SYNCHRONIZED_EXPR:
|
||||
wfl_op1 = TREE_OPERAND (node, 0);
|
||||
COMPLETE_CHECK_OP_0 (node);
|
||||
COMPLETE_CHECK_OP_1 (node);
|
||||
return patch_synchronized_statement (node, wfl_op1);
|
||||
|
||||
case TRY_EXPR:
|
||||
return patch_try_statement (node);
|
||||
|
||||
case CLEANUP_POINT_EXPR:
|
||||
COMPLETE_CHECK_OP_0 (node);
|
||||
TREE_TYPE (node) = void_type_node;
|
||||
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
|
||||
return node;
|
||||
|
||||
case WITH_CLEANUP_EXPR:
|
||||
COMPLETE_CHECK_OP_0 (node);
|
||||
COMPLETE_CHECK_OP_2 (node);
|
||||
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
|
||||
TREE_TYPE (node) = void_type_node;
|
||||
return node;
|
||||
|
||||
case LABELED_BLOCK_EXPR:
|
||||
PUSH_LABELED_BLOCK (node);
|
||||
if (LABELED_BLOCK_BODY (node))
|
||||
@ -13378,12 +13389,19 @@ static tree
|
||||
patch_synchronized_statement (node, wfl_op1)
|
||||
tree node, wfl_op1;
|
||||
{
|
||||
tree expr = TREE_OPERAND (node, 0);
|
||||
tree expr = java_complete_tree (TREE_OPERAND (node, 0));
|
||||
tree block = TREE_OPERAND (node, 1);
|
||||
tree try_block, catch_all, stmt, compound, decl;
|
||||
|
||||
tree enter, exit, finally, expr_decl;
|
||||
|
||||
if (expr == error_mark_node)
|
||||
{
|
||||
block = java_complete_tree (block);
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* The TYPE of expr must be a reference type */
|
||||
if (!JREFERENCE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0))))
|
||||
if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
|
||||
{
|
||||
SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
|
||||
parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
|
||||
@ -13409,34 +13427,23 @@ patch_synchronized_statement (node, wfl_op1)
|
||||
Throw (e);
|
||||
} */
|
||||
|
||||
/* TRY block */
|
||||
BUILD_MONITOR_ENTER (stmt, expr);
|
||||
compound = add_stmt_to_compound (NULL_TREE, int_type_node, stmt);
|
||||
compound = add_stmt_to_compound (compound, void_type_node, block);
|
||||
if (CAN_COMPLETE_NORMALLY (block))
|
||||
{
|
||||
BUILD_MONITOR_EXIT (stmt, expr);
|
||||
compound = add_stmt_to_compound (compound, int_type_node, stmt);
|
||||
}
|
||||
try_block = build_expr_block (compound, NULL_TREE);
|
||||
CAN_COMPLETE_NORMALLY (try_block) = CAN_COMPLETE_NORMALLY (block);
|
||||
expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
|
||||
BUILD_MONITOR_ENTER (enter, expr_decl);
|
||||
BUILD_MONITOR_EXIT (exit, expr_decl);
|
||||
CAN_COMPLETE_NORMALLY (enter) = 1;
|
||||
CAN_COMPLETE_NORMALLY (exit) = 1;
|
||||
node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
|
||||
build (COMPOUND_EXPR, NULL_TREE,
|
||||
build (WITH_CLEANUP_EXPR, NULL_TREE,
|
||||
build (COMPOUND_EXPR, NULL_TREE,
|
||||
build (MODIFY_EXPR, NULL_TREE,
|
||||
expr_decl, expr),
|
||||
enter),
|
||||
NULL_TREE, exit),
|
||||
block));
|
||||
node = build_expr_block (node, expr_decl);
|
||||
|
||||
/* CATCH_ALL block */
|
||||
decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
|
||||
BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl);
|
||||
compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt);
|
||||
BUILD_MONITOR_EXIT (stmt, expr);
|
||||
compound = add_stmt_to_compound (compound, int_type_node, stmt);
|
||||
BUILD_THROW (stmt, decl);
|
||||
compound = add_stmt_to_compound (compound, void_type_node, stmt);
|
||||
catch_all = build_expr_block (compound, decl);
|
||||
catch_all = build_expr_block (catch_all, NULL_TREE);
|
||||
catch_all = build1 (CATCH_EXPR, void_type_node, catch_all);
|
||||
|
||||
/* TRY-CATCH statement */
|
||||
compound = build (TRY_EXPR, void_type_node, try_block, catch_all, NULL_TREE);
|
||||
CAN_COMPLETE_NORMALLY (compound) = CAN_COMPLETE_NORMALLY (try_block);
|
||||
return compound;
|
||||
return java_complete_tree (node);
|
||||
}
|
||||
|
||||
/* 14.16 The throw Statement */
|
||||
@ -13764,7 +13771,7 @@ fold_constant_for_init (node, context)
|
||||
if (val == NULL_TREE || ! TREE_CONSTANT (val))
|
||||
return NULL_TREE;
|
||||
TREE_OPERAND (node, 0) = val;
|
||||
node = patch_unaryop (node, op0);
|
||||
return patch_unaryop (node, op0);
|
||||
break;
|
||||
|
||||
case COND_EXPR:
|
||||
|
@ -7491,13 +7491,24 @@ java_complete_lhs (node)
|
||||
|
||||
case SYNCHRONIZED_EXPR:
|
||||
wfl_op1 = TREE_OPERAND (node, 0);
|
||||
COMPLETE_CHECK_OP_0 (node);
|
||||
COMPLETE_CHECK_OP_1 (node);
|
||||
return patch_synchronized_statement (node, wfl_op1);
|
||||
|
||||
case TRY_EXPR:
|
||||
return patch_try_statement (node);
|
||||
|
||||
case CLEANUP_POINT_EXPR:
|
||||
COMPLETE_CHECK_OP_0 (node);
|
||||
TREE_TYPE (node) = void_type_node;
|
||||
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
|
||||
return node;
|
||||
|
||||
case WITH_CLEANUP_EXPR:
|
||||
COMPLETE_CHECK_OP_0 (node);
|
||||
COMPLETE_CHECK_OP_2 (node);
|
||||
CAN_COMPLETE_NORMALLY (node) = CAN_COMPLETE_NORMALLY (TREE_OPERAND (node, 0));
|
||||
TREE_TYPE (node) = void_type_node;
|
||||
return node;
|
||||
|
||||
case LABELED_BLOCK_EXPR:
|
||||
PUSH_LABELED_BLOCK (node);
|
||||
if (LABELED_BLOCK_BODY (node))
|
||||
@ -10740,12 +10751,19 @@ static tree
|
||||
patch_synchronized_statement (node, wfl_op1)
|
||||
tree node, wfl_op1;
|
||||
{
|
||||
tree expr = TREE_OPERAND (node, 0);
|
||||
tree expr = java_complete_tree (TREE_OPERAND (node, 0));
|
||||
tree block = TREE_OPERAND (node, 1);
|
||||
tree try_block, catch_all, stmt, compound, decl;
|
||||
|
||||
tree enter, exit, finally, expr_decl;
|
||||
|
||||
if (expr == error_mark_node)
|
||||
{
|
||||
block = java_complete_tree (block);
|
||||
return expr;
|
||||
}
|
||||
|
||||
/* The TYPE of expr must be a reference type */
|
||||
if (!JREFERENCE_TYPE_P (TREE_TYPE (TREE_OPERAND (node, 0))))
|
||||
if (!JREFERENCE_TYPE_P (TREE_TYPE (expr)))
|
||||
{
|
||||
SET_WFL_OPERATOR (wfl_operator, node, wfl_op1);
|
||||
parse_error_context (wfl_operator, "Incompatible type for `synchronized'"
|
||||
@ -10771,34 +10789,23 @@ patch_synchronized_statement (node, wfl_op1)
|
||||
Throw (e);
|
||||
} */
|
||||
|
||||
/* TRY block */
|
||||
BUILD_MONITOR_ENTER (stmt, expr);
|
||||
compound = add_stmt_to_compound (NULL_TREE, int_type_node, stmt);
|
||||
compound = add_stmt_to_compound (compound, void_type_node, block);
|
||||
if (CAN_COMPLETE_NORMALLY (block))
|
||||
{
|
||||
BUILD_MONITOR_EXIT (stmt, expr);
|
||||
compound = add_stmt_to_compound (compound, int_type_node, stmt);
|
||||
}
|
||||
try_block = build_expr_block (compound, NULL_TREE);
|
||||
CAN_COMPLETE_NORMALLY (try_block) = CAN_COMPLETE_NORMALLY (block);
|
||||
expr_decl = build_decl (VAR_DECL, generate_name (), TREE_TYPE (expr));
|
||||
BUILD_MONITOR_ENTER (enter, expr_decl);
|
||||
BUILD_MONITOR_EXIT (exit, expr_decl);
|
||||
CAN_COMPLETE_NORMALLY (enter) = 1;
|
||||
CAN_COMPLETE_NORMALLY (exit) = 1;
|
||||
node = build1 (CLEANUP_POINT_EXPR, NULL_TREE,
|
||||
build (COMPOUND_EXPR, NULL_TREE,
|
||||
build (WITH_CLEANUP_EXPR, NULL_TREE,
|
||||
build (COMPOUND_EXPR, NULL_TREE,
|
||||
build (MODIFY_EXPR, NULL_TREE,
|
||||
expr_decl, expr),
|
||||
enter),
|
||||
NULL_TREE, exit),
|
||||
block));
|
||||
node = build_expr_block (node, expr_decl);
|
||||
|
||||
/* CATCH_ALL block */
|
||||
decl = build_decl (VAR_DECL, generate_name (), ptr_type_node);
|
||||
BUILD_ASSIGN_EXCEPTION_INFO (stmt, decl);
|
||||
compound = add_stmt_to_compound (NULL_TREE, void_type_node, stmt);
|
||||
BUILD_MONITOR_EXIT (stmt, expr);
|
||||
compound = add_stmt_to_compound (compound, int_type_node, stmt);
|
||||
BUILD_THROW (stmt, decl);
|
||||
compound = add_stmt_to_compound (compound, void_type_node, stmt);
|
||||
catch_all = build_expr_block (compound, decl);
|
||||
catch_all = build_expr_block (catch_all, NULL_TREE);
|
||||
catch_all = build1 (CATCH_EXPR, void_type_node, catch_all);
|
||||
|
||||
/* TRY-CATCH statement */
|
||||
compound = build (TRY_EXPR, void_type_node, try_block, catch_all, NULL_TREE);
|
||||
CAN_COMPLETE_NORMALLY (compound) = CAN_COMPLETE_NORMALLY (try_block);
|
||||
return compound;
|
||||
return java_complete_tree (node);
|
||||
}
|
||||
|
||||
/* 14.16 The throw Statement */
|
||||
@ -11126,7 +11133,7 @@ fold_constant_for_init (node, context)
|
||||
if (val == NULL_TREE || ! TREE_CONSTANT (val))
|
||||
return NULL_TREE;
|
||||
TREE_OPERAND (node, 0) = val;
|
||||
node = patch_unaryop (node, op0);
|
||||
return patch_unaryop (node, op0);
|
||||
break;
|
||||
|
||||
case COND_EXPR:
|
||||
|
@ -1035,10 +1035,10 @@ verify_jvm_instructions (jcf, byte_ops, length)
|
||||
int nlocals = DECL_MAX_LOCALS (current_function_decl);
|
||||
index = nlocals + DECL_MAX_STACK (current_function_decl);
|
||||
return_type_map = make_tree_vec (index);
|
||||
while (--index >= nlocals)
|
||||
TREE_VEC_ELT (return_type_map, index) = TYPE_UNKNOWN;
|
||||
while (--index >= 0)
|
||||
TREE_VEC_ELT (return_type_map, index) = TYPE_UNUSED;
|
||||
while (index > nlocals)
|
||||
TREE_VEC_ELT (return_type_map, --index) = TYPE_UNKNOWN;
|
||||
while (index > 0)
|
||||
TREE_VEC_ELT (return_type_map, --index) = TYPE_UNUSED;
|
||||
LABEL_RETURN_LABEL (target)
|
||||
= build_decl (LABEL_DECL, NULL_TREE, TREE_TYPE (target));
|
||||
LABEL_PC (LABEL_RETURN_LABEL (target)) = -1;
|
||||
|
Loading…
Reference in New Issue
Block a user