diff options
author | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-06-22 23:22:13 +0000 |
---|---|---|
committer | tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4> | 1999-06-22 23:22:13 +0000 |
commit | 1e4f52d1971de1c5296073c5ad58874f12823e35 (patch) | |
tree | ade4778ad996d42dbabf9b42c45bfe8013509046 | |
parent | 0663299a0d5385a203fda58d44d2056be3563c6d (diff) | |
download | gcc-1e4f52d1971de1c5296073c5ad58874f12823e35.tar.gz |
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.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27710 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcc/java/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/java/parse-scan.c | 6 | ||||
-rw-r--r-- | gcc/java/parse.c | 6 | ||||
-rw-r--r-- | gcc/java/verify.c | 124 |
4 files changed, 74 insertions, 67 deletions
diff --git a/gcc/java/ChangeLog b/gcc/java/ChangeLog index 4136698a65e..0bea5674335 100644 --- a/gcc/java/ChangeLog +++ b/gcc/java/ChangeLog @@ -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 diff --git a/gcc/java/parse-scan.c b/gcc/java/parse-scan.c index fcc19aa63cc..27b42862fef 100644 --- a/gcc/java/parse-scan.c +++ b/gcc/java/parse-scan.c @@ -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; diff --git a/gcc/java/parse.c b/gcc/java/parse.c index fb032c98fa3..7dcd87efeff 100644 --- a/gcc/java/parse.c +++ b/gcc/java/parse.c @@ -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; diff --git a/gcc/java/verify.c b/gcc/java/verify.c index ead4ea6ec1f..e367334c462 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 |