diff options
author | Andrew Haley <aph@cygnus.com> | 1999-06-22 23:22:13 +0000 |
---|---|---|
committer | Tom Tromey <tromey@gcc.gnu.org> | 1999-06-22 23:22:13 +0000 |
commit | 45b0aa3189da598a2c9e24481970d1bcc22c69c1 (patch) | |
tree | ade4778ad996d42dbabf9b42c45bfe8013509046 /gcc/java/verify.c | |
parent | 99d60508020fb9023b3d1e3ab54a0fb2f66cb0c4 (diff) | |
download | gcc-45b0aa3189da598a2c9e24481970d1bcc22c69c1.zip gcc-45b0aa3189da598a2c9e24481970d1bcc22c69c1.tar.gz gcc-45b0aa3189da598a2c9e24481970d1bcc22c69c1.tar.bz2 |
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
Diffstat (limited to 'gcc/java/verify.c')
-rw-r--r-- | gcc/java/verify.c | 124 |
1 files changed, 63 insertions, 61 deletions
diff --git a/gcc/java/verify.c b/gcc/java/verify.c index ead4ea6..e367334 100644 --- a/gcc/java/verify.c +++ b/gcc/java/verify.c @@ -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 |