verify.c (verify_jvm_instructions): Check for pending blocks before invalid PC test and opcode switch, not after.

1999-06-22  Andrew Haley  <aph@cygnus.com>
	* verify.c (verify_jvm_instructions): Check for pending blocks
	before invalid PC test and opcode switch, not after.

From-SVN: r27710
This commit is contained in:
Andrew Haley 1999-06-22 23:22:13 +00:00 committed by Tom Tromey
parent 99d6050802
commit 45b0aa3189
4 changed files with 74 additions and 67 deletions

View File

@ -1,3 +1,8 @@
1999-06-22 Andrew Haley <aph@cygnus.com>
* verify.c (verify_jvm_instructions): Check for pending blocks
before invalid PC test and opcode switch, not after.
1999-06-21 Andrew Haley <aph@cygnus.com>
* except.c (find_handler_in_range): The upper limit for exception

View File

@ -1375,7 +1375,7 @@ static const short yycheck[] = { 3,
#define YYPURE 1
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/x1/java/install/share/bison.simple"
#line 3 "/x1/java/posix/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@ -1568,7 +1568,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
#line 196 "/x1/java/install/share/bison.simple"
#line 196 "/x1/java/posix/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@ -2156,7 +2156,7 @@ case 337:
break;}
}
/* the action file gets copied in in place of this dollarsign */
#line 498 "/x1/java/install/share/bison.simple"
#line 498 "/x1/java/posix/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;

View File

@ -2211,7 +2211,7 @@ static const short yycheck[] = { 3,
#define YYPURE 1
/* -*-C-*- Note some compilers choke on comments on `#line' lines. */
#line 3 "/usr/lib/bison.simple"
#line 3 "/x1/java/posix/share/bison.simple"
/* Skeleton output parser for bison,
Copyright (C) 1984, 1989, 1990 Free Software Foundation, Inc.
@ -2404,7 +2404,7 @@ __yy_memcpy (char *to, char *from, int count)
#endif
#endif
#line 196 "/usr/lib/bison.simple"
#line 196 "/x1/java/posix/share/bison.simple"
/* The user can define YYPARSE_PARAM as the name of an argument to be passed
into yyparse. The argument should have type void *.
@ -4693,7 +4693,7 @@ case 495:
break;}
}
/* the action file gets copied in in place of this dollarsign */
#line 498 "/usr/lib/bison.simple"
#line 498 "/x1/java/posix/share/bison.simple"
yyvsp -= yylen;
yyssp -= yylen;

View File

@ -427,6 +427,67 @@ verify_jvm_instructions (jcf, byte_ops, length)
PUSH_PENDING (lookup_label (PC));
INVALIDATE_PC;
}
/* Check if there are any more pending blocks in the current
subroutine. Because we push pending blocks in a
last-in-first-out order, and because we don't push anything
from our caller until we are done with this subroutine or
anything nested in it, then we are done if the top of the
pending_blocks stack is not in a subroutine, or it is in our
caller. */
if (current_subr
&& PC == INVALID_PC)
{
tree caller = LABEL_SUBR_CONTEXT (current_subr);
if (pending_blocks == NULL_TREE
|| ! LABEL_IN_SUBR (pending_blocks)
|| LABEL_SUBR_START (pending_blocks) == caller)
{
int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
tmp = LABEL_RETURN_LABELS (current_subr);
/* FIXME: If we exit a subroutine via a throw, we might
have returned to an earlier caller. Obviously a
"ret" can only return one level, but a throw may
return many levels.*/
current_subr = caller;
if (RETURN_MAP_ADJUSTED (ret_map))
{
/* Since we are done with this subroutine , set up
the (so far known) return address as pending -
with the merged type state. */
for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
{
tree return_label = TREE_VALUE (tmp);
tree return_state = LABEL_TYPE_STATE (return_label);
if (return_state == NULL_TREE)
{
/* This means means we had not verified the
subroutine earlier, so this is the first jsr to
call it. In this case, the type_map of the return
address is just the current type_map - and that
is handled by the following PUSH_PENDING. */
}
else
{
/* In this case we have to do a merge. But first
restore the type_map for unused slots to those
that were in effect at the jsr. */
for (index = size; --index >= 0; )
{
type_map[index] = TREE_VEC_ELT (ret_map, index);
if (type_map[index] == TYPE_UNUSED)
type_map[index]
= TREE_VEC_ELT (return_state, index);
}
}
PUSH_PENDING (return_label);
}
}
}
}
if (PC == INVALID_PC)
{
label = pending_blocks;
@ -449,6 +510,8 @@ verify_jvm_instructions (jcf, byte_ops, length)
else if (PC >= length)
VERIFICATION_ERROR ("falling through end of method");
/* fprintf (stderr, "** %d\n", PC); */
oldpc = PC;
if (!(instruction_bits [PC] & BCODE_INSTRUCTION_START) && ! wide)
@ -1208,67 +1271,6 @@ verify_jvm_instructions (jcf, byte_ops, length)
return 0;
}
/* Check if there are any more pending blocks in this subroutine.
Because we push pending blocks in a last-in-first-out order,
and because we don't push anything from our caller until we
are done with this subroutine or anything nested in it,
then we are done if the top of the pending_blocks stack is
not in a subroutine, or it is in our caller. */
if (current_subr
&& PC == INVALID_PC)
{
tree caller = LABEL_SUBR_CONTEXT (current_subr);
if (pending_blocks == NULL_TREE
|| ! LABEL_IN_SUBR (pending_blocks)
|| LABEL_SUBR_START (pending_blocks) == caller)
{
int size = DECL_MAX_LOCALS(current_function_decl)+stack_pointer;
tree ret_map = LABEL_RETURN_TYPE_STATE (current_subr);
tmp = LABEL_RETURN_LABELS (current_subr);
/* FIXME: If we exit a subroutine via a throw, we might
have returned to an earlier caller. Obviously a
"ret" can only return one level, but a throw may
return many levels.*/
current_subr = caller;
if (RETURN_MAP_ADJUSTED (ret_map))
{
/* Since we are done with this subroutine , set up
the (so far known) return address as pending -
with the merged type state. */
for ( ; tmp != NULL_TREE; tmp = TREE_CHAIN (tmp))
{
tree return_label = TREE_VALUE (tmp);
tree return_state = LABEL_TYPE_STATE (return_label);
if (return_state == NULL_TREE)
{
/* This means means we had not verified the
subroutine earlier, so this is the first jsr to
call it. In this case, the type_map of the return
address is just the current type_map - and that
is handled by the following PUSH_PENDING. */
}
else
{
/* In this case we have to do a merge. But first
restore the type_map for unused slots to those
that were in effect at the jsr. */
for (index = size; --index >= 0; )
{
type_map[index] = TREE_VEC_ELT (ret_map, index);
if (type_map[index] == TYPE_UNUSED)
type_map[index]
= TREE_VEC_ELT (return_state, index);
}
}
PUSH_PENDING (return_label);
}
}
}
}
prevpc = oldpc;
/* The following test is true if we have entered or exited an exception