Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
R
riscv-gcc-1
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
lvzhengyang
riscv-gcc-1
Commits
984ad2c6
Commit
984ad2c6
authored
Jan 14, 2001
by
Per Bothner
Committed by
Per Bothner
Jan 14, 2001
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Various patches to emit better messages on verification errors.
From-SVN: r39019
parent
150d3c00
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
171 additions
and
78 deletions
+171
-78
gcc/java/ChangeLog
+15
-0
gcc/java/expr.c
+53
-29
gcc/java/java-tree.h
+8
-2
gcc/java/verify.c
+95
-47
No files found.
gcc/java/ChangeLog
View file @
984ad2c6
2001-01-14 Per Bothner <per@bothner.com>
2001-01-14 Per Bothner <per@bothner.com>
Various patches to emit better messages on verification errors.
* expr.c (push_type_0): Return error indication on stack overflow,
instead of callinfg fatal.
(push_type): Now just call push_type_0 (nd fatal on overflow).
(pop_type_0): Return detailed error message (in a char** argument).
(pop_type): If pop_type_0 fails, print error message.
(pop_argument_types): Moved to verify.c.
* verify.c (pop_argument_types): Moved from expr.c.
Return a (possible) error message, rather than void.
(POP_TYPE, POP_TYPE_CONV, PUSH_TYPE, PUSH_PENDING): New macros.
(verify_jvm_instruction): Use new macros, improving error messages.
For case OPCODE_astore use object_ptr_type_node.
* java-tree.h (TYPE_UNDERFLOW, TYPE_UNEXPECTED): New macros.
(pop_type_0, push_type_0, pop_argument_types): Update accordingly.
* parse.y (java_complete_lhs case EXPR_WITH_FILE_LOCATION): If body is
* parse.y (java_complete_lhs case EXPR_WITH_FILE_LOCATION): If body is
constant, return body without wrapper. (Improves constant folding.)
constant, return body without wrapper. (Improves constant folding.)
* lex.c (build_wfl_node): Clear TREE_TYPE from returned node.
* lex.c (build_wfl_node): Clear TREE_TYPE from returned node.
...
...
gcc/java/expr.c
View file @
984ad2c6
...
@@ -256,19 +256,31 @@ flush_quick_stack ()
...
@@ -256,19 +256,31 @@ flush_quick_stack ()
}
}
}
}
void
/* Push TYPE on the type stack.
push_type
(
type
)
Return true on success, 0 on overflow. */
int
push_type_0
(
type
)
tree
type
;
tree
type
;
{
{
int
n_words
;
int
n_words
;
type
=
promote_type
(
type
);
type
=
promote_type
(
type
);
n_words
=
1
+
TYPE_IS_WIDE
(
type
);
n_words
=
1
+
TYPE_IS_WIDE
(
type
);
if
(
stack_pointer
+
n_words
>
DECL_MAX_STACK
(
current_function_decl
))
if
(
stack_pointer
+
n_words
>
DECL_MAX_STACK
(
current_function_decl
))
fatal
(
"stack overflow"
)
;
return
0
;
stack_type_map
[
stack_pointer
++
]
=
type
;
stack_type_map
[
stack_pointer
++
]
=
type
;
n_words
--
;
n_words
--
;
while
(
--
n_words
>=
0
)
while
(
--
n_words
>=
0
)
stack_type_map
[
stack_pointer
++
]
=
TYPE_SECOND
;
stack_type_map
[
stack_pointer
++
]
=
TYPE_SECOND
;
return
1
;
}
void
push_type
(
type
)
tree
type
;
{
if
(
!
push_type_0
(
type
))
fatal
(
"stack overflow"
);
}
}
static
void
static
void
...
@@ -296,23 +308,32 @@ push_value (value)
...
@@ -296,23 +308,32 @@ push_value (value)
/* Pop a type from the type stack.
/* Pop a type from the type stack.
TYPE is the expected type. Return the actual type, which must be
TYPE is the expected type. Return the actual type, which must be
convertible to TYPE, otherwise NULL_TREE is returned. */
convertible to TYPE.
On an error, *MESSAGEP is set to a freshly malloc'd error message. */
tree
tree
pop_type_0
(
type
)
pop_type_0
(
type
,
messagep
)
tree
type
;
tree
type
;
char
**
messagep
;
{
{
int
n_words
;
int
n_words
;
tree
t
;
tree
t
;
*
messagep
=
NULL
;
if
(
TREE_CODE
(
type
)
==
RECORD_TYPE
)
if
(
TREE_CODE
(
type
)
==
RECORD_TYPE
)
type
=
promote_type
(
type
);
type
=
promote_type
(
type
);
n_words
=
1
+
TYPE_IS_WIDE
(
type
);
n_words
=
1
+
TYPE_IS_WIDE
(
type
);
if
(
stack_pointer
<
n_words
)
if
(
stack_pointer
<
n_words
)
fatal
(
"stack underflow"
);
{
*
messagep
=
xstrdup
(
"stack underflow"
);
return
type
;
}
while
(
--
n_words
>
0
)
while
(
--
n_words
>
0
)
{
{
if
(
stack_type_map
[
--
stack_pointer
]
!=
void_type_node
)
if
(
stack_type_map
[
--
stack_pointer
]
!=
void_type_node
)
fatal
(
"Invalid multi-word value on type stack"
);
{
*
messagep
=
xstrdup
(
"Invalid multi-word value on type stack"
);
return
type
;
}
}
}
t
=
stack_type_map
[
--
stack_pointer
];
t
=
stack_type_map
[
--
stack_pointer
];
if
(
type
==
NULL_TREE
||
t
==
type
)
if
(
type
==
NULL_TREE
||
t
==
type
)
...
@@ -334,7 +355,24 @@ pop_type_0 (type)
...
@@ -334,7 +355,24 @@ pop_type_0 (type)
/* FIXME: this is worse than a kludge, probably. */
/* FIXME: this is worse than a kludge, probably. */
return
object_ptr_type_node
;
return
object_ptr_type_node
;
}
}
return
NULL_TREE
;
{
const
char
*
str1
=
"expected type '"
;
const
char
*
str3
=
"' but stack contains '"
;
const
char
*
str5
=
"'"
;
int
len1
=
strlen
(
str1
);
int
len2
=
strlen
(
lang_printable_name
(
type
,
0
));
int
len3
=
strlen
(
str3
);
int
len4
=
strlen
(
lang_printable_name
(
t
,
0
));
int
len5
=
strlen
(
str5
);
char
*
msg
=
xmalloc
(
len1
+
len2
+
len3
+
len4
+
len5
+
1
);
*
messagep
=
msg
;
strcpy
(
msg
,
str1
);
msg
+=
len1
;
strcpy
(
msg
,
lang_printable_name
(
type
,
0
));
msg
+=
len2
;
strcpy
(
msg
,
str3
);
msg
+=
len3
;
strcpy
(
msg
,
lang_printable_name
(
t
,
0
));
msg
+=
len4
;
strcpy
(
msg
,
str5
);
return
type
;
}
}
}
/* Pop a type from the type stack.
/* Pop a type from the type stack.
...
@@ -345,10 +383,13 @@ tree
...
@@ -345,10 +383,13 @@ tree
pop_type
(
type
)
pop_type
(
type
)
tree
type
;
tree
type
;
{
{
tree
t
=
pop_type_0
(
type
);
char
*
message
=
NULL
;
if
(
t
!=
NULL_TREE
)
type
=
pop_type_0
(
type
,
&
message
);
return
t
;
if
(
message
!=
NULL
)
error
(
"unexpected type on stack"
);
{
error
(
message
);
free
(
message
);
}
return
type
;
return
type
;
}
}
...
@@ -1576,23 +1617,6 @@ expand_java_ret (return_address)
...
@@ -1576,23 +1617,6 @@ expand_java_ret (return_address)
}
}
#endif
#endif
/* Recursive helper function to pop argument types during verifiation. */
void
pop_argument_types
(
arg_types
)
tree
arg_types
;
{
if
(
arg_types
==
end_params_node
)
return
;
if
(
TREE_CODE
(
arg_types
)
==
TREE_LIST
)
{
pop_argument_types
(
TREE_CHAIN
(
arg_types
));
pop_type
(
TREE_VALUE
(
arg_types
));
return
;
}
abort
();
}
static
tree
static
tree
pop_arguments
(
arg_types
)
pop_arguments
(
arg_types
)
tree
arg_types
;
tree
arg_types
;
...
...
gcc/java/java-tree.h
View file @
984ad2c6
...
@@ -978,9 +978,8 @@ extern tree build_java_array_type PARAMS ((tree, HOST_WIDE_INT));
...
@@ -978,9 +978,8 @@ extern tree build_java_array_type PARAMS ((tree, HOST_WIDE_INT));
extern
int
is_compiled_class
PARAMS
((
tree
));
extern
int
is_compiled_class
PARAMS
((
tree
));
extern
tree
mangled_classname
PARAMS
((
const
char
*
,
tree
));
extern
tree
mangled_classname
PARAMS
((
const
char
*
,
tree
));
extern
tree
lookup_label
PARAMS
((
int
));
extern
tree
lookup_label
PARAMS
((
int
));
extern
tree
pop_type_0
PARAMS
((
tree
));
extern
tree
pop_type_0
PARAMS
((
tree
,
char
**
));
extern
tree
pop_type
PARAMS
((
tree
));
extern
tree
pop_type
PARAMS
((
tree
));
extern
void
pop_argument_types
PARAMS
((
tree
));
extern
tree
decode_newarray_type
PARAMS
((
int
));
extern
tree
decode_newarray_type
PARAMS
((
int
));
extern
tree
lookup_field
PARAMS
((
tree
*
,
tree
));
extern
tree
lookup_field
PARAMS
((
tree
*
,
tree
));
extern
int
is_array_type_p
PARAMS
((
tree
));
extern
int
is_array_type_p
PARAMS
((
tree
));
...
@@ -1057,6 +1056,7 @@ extern int process_jvm_instruction PARAMS ((int, const unsigned char *, long));
...
@@ -1057,6 +1056,7 @@ extern int process_jvm_instruction PARAMS ((int, const unsigned char *, long));
extern
int
maybe_adjust_start_pc
PARAMS
((
struct
JCF
*
,
int
,
int
,
int
));
extern
int
maybe_adjust_start_pc
PARAMS
((
struct
JCF
*
,
int
,
int
,
int
));
extern
void
set_local_type
PARAMS
((
int
,
tree
));
extern
void
set_local_type
PARAMS
((
int
,
tree
));
extern
int
merge_type_state
PARAMS
((
tree
));
extern
int
merge_type_state
PARAMS
((
tree
));
extern
int
push_type_0
PARAMS
((
tree
));
extern
void
push_type
PARAMS
((
tree
));
extern
void
push_type
PARAMS
((
tree
));
extern
void
load_type_state
PARAMS
((
tree
));
extern
void
load_type_state
PARAMS
((
tree
));
extern
void
add_interface
PARAMS
((
tree
,
tree
));
extern
void
add_interface
PARAMS
((
tree
,
tree
));
...
@@ -1244,6 +1244,12 @@ extern int linenumber_count;
...
@@ -1244,6 +1244,12 @@ extern int linenumber_count;
used nor set in the subroutine. */
used nor set in the subroutine. */
#define TYPE_UNUSED error_mark_node
#define TYPE_UNUSED error_mark_node
/* When returned from pop_type_0, indicates stack underflow. */
#define TYPE_UNDERFLOW integer_zero_node
/* When returned from pop_type_0, indicates a type mismatch. */
#define TYPE_UNEXPECTED NULL_TREE
/* A array mapping variable/stack slot index to the type current
/* A array mapping variable/stack slot index to the type current
in that variable/stack slot.
in that variable/stack slot.
TYPE_UNKNOWN, TYPE_SECOND, and TYPE_NULL are special cases. */
TYPE_UNKNOWN, TYPE_SECOND, and TYPE_NULL are special cases. */
...
...
gcc/java/verify.c
View file @
984ad2c6
...
@@ -348,9 +348,43 @@ start_pc_cmp (xp, yp)
...
@@ -348,9 +348,43 @@ start_pc_cmp (xp, yp)
#define VERIFICATION_ERROR(MESSAGE) \
#define VERIFICATION_ERROR(MESSAGE) \
do { message = MESSAGE; goto verify_error; } while (0)
do { message = MESSAGE; goto verify_error; } while (0)
/* Recursive helper function to pop argument types during verifiation.
ARG_TYPES is the list of formal parameter types.
Return NULL on success and a freshly malloc'd error message on failure. */
static
char
*
pop_argument_types
(
arg_types
)
tree
arg_types
;
{
if
(
arg_types
==
end_params_node
)
return
NULL
;
if
(
TREE_CODE
(
arg_types
)
==
TREE_LIST
)
{
char
*
message
=
pop_argument_types
(
TREE_CHAIN
(
arg_types
));
if
(
message
==
NULL
)
pop_type_0
(
TREE_VALUE
(
arg_types
),
&
message
);
return
message
;
}
abort
();
}
#define POP_TYPE(TYPE, MESSAGE) \
do { pmessage = NULL; pop_type_0 (TYPE, &pmessage); \
if (pmessage != NULL) goto pop_type_error; \
} while (0)
#define POP_TYPE_CONV(TYPE, POPPED_TYPE, MESSAGE) \
do { pmessage = NULL; POPPED_TYPE = pop_type_0 (TYPE, &pmessage); \
if (pmessage != NULL) goto pop_type_error; \
} while (0)
#define PUSH_TYPE(TYPE) \
do { if (! push_type_0 (TYPE)) { goto stack_overflow; }} while (0)
#define PUSH_PENDING(LABEL) \
#define PUSH_PENDING(LABEL) \
do { if ((message = check_pending_block (LABEL)) != NULL) \
do { tree tmplab = LABEL; \
goto verify_error; } while (0)
if ((message = check_pending_block (tmplab)) != NULL) \
{ oldpc = LABEL_PC (tmplab); goto verify_error; }} while (0)
#ifdef __GNUC__
#ifdef __GNUC__
#define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
#define CHECK_PC_IN_RANGE(PC) ({if (PC < 0 || PC > length) goto bad_pc; (void)1;})
...
@@ -376,6 +410,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -376,6 +410,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
int
oldpc
=
0
;
/* PC of start of instruction. */
int
oldpc
=
0
;
/* PC of start of instruction. */
int
prevpc
=
0
;
/* If >= 0, PC of previous instruction. */
int
prevpc
=
0
;
/* If >= 0, PC of previous instruction. */
const
char
*
message
;
const
char
*
message
;
char
*
pmessage
;
int
i
;
int
i
;
register
unsigned
char
*
p
;
register
unsigned
char
*
p
;
struct
eh_range
*
prev_eh_ranges
=
NULL_EH_RANGE
;
struct
eh_range
*
prev_eh_ranges
=
NULL_EH_RANGE
;
...
@@ -559,13 +594,13 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -559,13 +594,13 @@ verify_jvm_instructions (jcf, byte_ops, length)
if
(
byte_ops
[
PC
]
==
OPCODE_newarray
if
(
byte_ops
[
PC
]
==
OPCODE_newarray
||
byte_ops
[
PC
]
==
OPCODE_newarray
)
||
byte_ops
[
PC
]
==
OPCODE_newarray
)
int_value
=
i
;
int_value
=
i
;
push_type
(
int_type_node
);
break
;
PUSH_TYPE
(
int_type_node
);
break
;
case
OPCODE_lconst_0
:
case
OPCODE_lconst_1
:
case
OPCODE_lconst_0
:
case
OPCODE_lconst_1
:
push_type
(
long_type_node
);
break
;
PUSH_TYPE
(
long_type_node
);
break
;
case
OPCODE_fconst_0
:
case
OPCODE_fconst_1
:
case
OPCODE_fconst_2
:
case
OPCODE_fconst_0
:
case
OPCODE_fconst_1
:
case
OPCODE_fconst_2
:
push_type
(
float_type_node
);
break
;
PUSH_TYPE
(
float_type_node
);
break
;
case
OPCODE_dconst_0
:
case
OPCODE_dconst_1
:
case
OPCODE_dconst_0
:
case
OPCODE_dconst_1
:
push_type
(
double_type_node
);
break
;
PUSH_TYPE
(
double_type_node
);
break
;
case
OPCODE_bipush
:
case
OPCODE_bipush
:
i
=
IMMEDIATE_s1
;
i
=
IMMEDIATE_s1
;
goto
push_int
;
goto
push_int
;
...
@@ -616,13 +651,13 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -616,13 +651,13 @@ verify_jvm_instructions (jcf, byte_ops, length)
?
(
!
INTEGRAL_TYPE_P
(
tmp
)
||
TYPE_PRECISION
(
tmp
)
>
32
)
?
(
!
INTEGRAL_TYPE_P
(
tmp
)
||
TYPE_PRECISION
(
tmp
)
>
32
)
:
type
!=
tmp
))
:
type
!=
tmp
))
VERIFICATION_ERROR
(
"invalid local variable type in load"
);
VERIFICATION_ERROR
(
"invalid local variable type in load"
);
push_type
(
tmp
);
PUSH_TYPE
(
tmp
);
goto
note_used
;
goto
note_used
;
case
OPCODE_istore
:
type
=
int_type_node
;
goto
general_store
;
case
OPCODE_istore
:
type
=
int_type_node
;
goto
general_store
;
case
OPCODE_lstore
:
type
=
long_type_node
;
goto
general_store
;
case
OPCODE_lstore
:
type
=
long_type_node
;
goto
general_store
;
case
OPCODE_fstore
:
type
=
float_type_node
;
goto
general_store
;
case
OPCODE_fstore
:
type
=
float_type_node
;
goto
general_store
;
case
OPCODE_dstore
:
type
=
double_type_node
;
goto
general_store
;
case
OPCODE_dstore
:
type
=
double_type_node
;
goto
general_store
;
case
OPCODE_astore
:
type
=
ptr_type_node
;
goto
general_store
;
case
OPCODE_astore
:
type
=
object_
ptr_type_node
;
goto
general_store
;
general_store
:
general_store
:
index
=
wide
?
IMMEDIATE_u2
:
IMMEDIATE_u1
;
index
=
wide
?
IMMEDIATE_u2
:
IMMEDIATE_u1
;
wide
=
0
;
wide
=
0
;
...
@@ -655,7 +690,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -655,7 +690,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
VERIFICATION_ERROR
(
"invalid local variable index in store"
);
VERIFICATION_ERROR
(
"invalid local variable index in store"
);
return
0
;
return
0
;
}
}
type
=
pop_type
(
type
);
POP_TYPE_CONV
(
type
,
type
,
NULL
);
type_map
[
index
]
=
type
;
type_map
[
index
]
=
type
;
/* If local variable changed, we need to reconsider eh handlers. */
/* If local variable changed, we need to reconsider eh handlers. */
...
@@ -723,19 +758,19 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -723,19 +758,19 @@ verify_jvm_instructions (jcf, byte_ops, length)
type
=
double_type_node
;
goto
unop
;
type
=
double_type_node
;
goto
unop
;
unop
:
unop
:
pop_type
(
type
);
pop_type
(
type
);
push_type
(
type
);
PUSH_TYPE
(
type
);
break
;
break
;
binop
:
binop
:
pop_type
(
type
);
pop_type
(
type
);
pop_type
(
type
);
pop_type
(
type
);
push_type
(
type
);
PUSH_TYPE
(
type
);
break
;
break
;
case
OPCODE_lshl
:
case
OPCODE_lshl
:
case
OPCODE_lshr
:
case
OPCODE_lshr
:
case
OPCODE_lushr
:
case
OPCODE_lushr
:
pop_type
(
int_type_node
);
pop_type
(
int_type_node
);
pop_type
(
long_type_node
);
pop_type
(
long_type_node
);
push_type
(
long_type_node
);
PUSH_TYPE
(
long_type_node
);
break
;
break
;
case
OPCODE_iinc
:
case
OPCODE_iinc
:
index
=
wide
?
IMMEDIATE_u2
:
IMMEDIATE_u1
;
index
=
wide
?
IMMEDIATE_u2
:
IMMEDIATE_u1
;
...
@@ -744,33 +779,34 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -744,33 +779,34 @@ verify_jvm_instructions (jcf, byte_ops, length)
if
(
index
<
0
||
index
>=
DECL_MAX_LOCALS
(
current_function_decl
))
if
(
index
<
0
||
index
>=
DECL_MAX_LOCALS
(
current_function_decl
))
VERIFICATION_ERROR
(
"invalid local variable index in iinc"
);
VERIFICATION_ERROR
(
"invalid local variable index in iinc"
);
tmp
=
type_map
[
index
];
tmp
=
type_map
[
index
];
if
(
!
INTEGRAL_TYPE_P
(
tmp
)
||
TYPE_PRECISION
(
tmp
)
>
32
)
if
(
tmp
==
NULL_TREE
||
!
INTEGRAL_TYPE_P
(
tmp
)
||
TYPE_PRECISION
(
tmp
)
>
32
)
VERIFICATION_ERROR
(
"invalid local variable type in iinc"
);
VERIFICATION_ERROR
(
"invalid local variable type in iinc"
);
break
;
break
;
case
OPCODE_i2l
:
case
OPCODE_i2l
:
pop_type
(
int_type_node
);
push_type
(
long_type_node
);
break
;
pop_type
(
int_type_node
);
PUSH_TYPE
(
long_type_node
);
break
;
case
OPCODE_i2f
:
case
OPCODE_i2f
:
pop_type
(
int_type_node
);
push_type
(
float_type_node
);
break
;
pop_type
(
int_type_node
);
PUSH_TYPE
(
float_type_node
);
break
;
case
OPCODE_i2d
:
case
OPCODE_i2d
:
pop_type
(
int_type_node
);
push_type
(
double_type_node
);
break
;
pop_type
(
int_type_node
);
PUSH_TYPE
(
double_type_node
);
break
;
case
OPCODE_l2i
:
case
OPCODE_l2i
:
pop_type
(
long_type_node
);
push_type
(
int_type_node
);
break
;
pop_type
(
long_type_node
);
PUSH_TYPE
(
int_type_node
);
break
;
case
OPCODE_l2f
:
case
OPCODE_l2f
:
pop_type
(
long_type_node
);
push_type
(
float_type_node
);
break
;
pop_type
(
long_type_node
);
PUSH_TYPE
(
float_type_node
);
break
;
case
OPCODE_l2d
:
case
OPCODE_l2d
:
pop_type
(
long_type_node
);
push_type
(
double_type_node
);
break
;
pop_type
(
long_type_node
);
PUSH_TYPE
(
double_type_node
);
break
;
case
OPCODE_f2i
:
case
OPCODE_f2i
:
pop_type
(
float_type_node
);
push_type
(
int_type_node
);
break
;
pop_type
(
float_type_node
);
PUSH_TYPE
(
int_type_node
);
break
;
case
OPCODE_f2l
:
case
OPCODE_f2l
:
pop_type
(
float_type_node
);
push_type
(
long_type_node
);
break
;
pop_type
(
float_type_node
);
PUSH_TYPE
(
long_type_node
);
break
;
case
OPCODE_f2d
:
case
OPCODE_f2d
:
pop_type
(
float_type_node
);
push_type
(
double_type_node
);
break
;
pop_type
(
float_type_node
);
PUSH_TYPE
(
double_type_node
);
break
;
case
OPCODE_d2i
:
case
OPCODE_d2i
:
pop_type
(
double_type_node
);
push_type
(
int_type_node
);
break
;
pop_type
(
double_type_node
);
PUSH_TYPE
(
int_type_node
);
break
;
case
OPCODE_d2l
:
case
OPCODE_d2l
:
pop_type
(
double_type_node
);
push_type
(
long_type_node
);
break
;
pop_type
(
double_type_node
);
PUSH_TYPE
(
long_type_node
);
break
;
case
OPCODE_d2f
:
case
OPCODE_d2f
:
pop_type
(
double_type_node
);
push_type
(
float_type_node
);
break
;
pop_type
(
double_type_node
);
PUSH_TYPE
(
float_type_node
);
break
;
case
OPCODE_lcmp
:
case
OPCODE_lcmp
:
type
=
long_type_node
;
goto
compare
;
type
=
long_type_node
;
goto
compare
;
case
OPCODE_fcmpl
:
case
OPCODE_fcmpl
:
...
@@ -781,7 +817,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -781,7 +817,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
type
=
double_type_node
;
goto
compare
;
type
=
double_type_node
;
goto
compare
;
compare
:
compare
:
pop_type
(
type
);
pop_type
(
type
);
pop_type
(
type
);
pop_type
(
type
);
push_type
(
int_type_node
);
break
;
PUSH_TYPE
(
int_type_node
);
break
;
case
OPCODE_ifeq
:
case
OPCODE_ifeq
:
case
OPCODE_ifne
:
case
OPCODE_ifne
:
case
OPCODE_iflt
:
case
OPCODE_iflt
:
...
@@ -848,10 +884,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -848,10 +884,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
if
(
type
!=
return_type
)
if
(
type
!=
return_type
)
VERIFICATION_ERROR
(
"incorrect ?return opcode"
);
VERIFICATION_ERROR
(
"incorrect ?return opcode"
);
if
(
type
!=
void_type_node
)
if
(
type
!=
void_type_node
)
{
POP_TYPE
(
type
,
"return value has wrong type"
);
if
(
pop_type_0
(
type
)
==
NULL_TREE
)
VERIFICATION_ERROR
(
"return value has wrong type"
);
}
INVALIDATE_PC
;
INVALIDATE_PC
;
break
;
break
;
case
OPCODE_getstatic
:
is_putting
=
0
;
is_static
=
1
;
goto
field
;
case
OPCODE_getstatic
:
is_putting
=
0
;
is_static
=
1
;
goto
field
;
...
@@ -864,22 +897,21 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -864,22 +897,21 @@ verify_jvm_instructions (jcf, byte_ops, length)
tree
field_signature
=
COMPONENT_REF_SIGNATURE
(
&
current_jcf
->
cpool
,
index
);
tree
field_signature
=
COMPONENT_REF_SIGNATURE
(
&
current_jcf
->
cpool
,
index
);
tree
field_type
=
get_type_from_signature
(
field_signature
);
tree
field_type
=
get_type_from_signature
(
field_signature
);
if
(
is_putting
)
if
(
is_putting
)
pop_type
(
field_type
);
POP_TYPE
(
field_type
,
"incorrect type for field"
);
if
(
!
is_static
)
if
(
!
is_static
)
{
{
int
clindex
=
COMPONENT_REF_CLASS_INDEX
(
&
current_jcf
->
cpool
,
int
clindex
=
COMPONENT_REF_CLASS_INDEX
(
&
current_jcf
->
cpool
,
index
);
index
);
tree
self_type
=
get_class_constant
(
current_jcf
,
clindex
);
tree
self_type
=
get_class_constant
(
current_jcf
,
clindex
);
/* Defer actual checking until next pass. */
/* Defer actual checking until next pass. */
if
(
pop_type_0
(
self_type
)
==
NULL_TREE
)
POP_TYPE
(
self_type
,
"incorrect type for field reference"
);
VERIFICATION_ERROR
(
"incorrect type for field reference"
);
}
}
if
(
!
is_putting
)
if
(
!
is_putting
)
push_type
(
field_type
);
PUSH_TYPE
(
field_type
);
break
;
break
;
}
}
case
OPCODE_new
:
case
OPCODE_new
:
push_type
(
get_class_constant
(
jcf
,
IMMEDIATE_u2
));
PUSH_TYPE
(
get_class_constant
(
jcf
,
IMMEDIATE_u2
));
break
;
break
;
case
OPCODE_dup
:
type_stack_dup
(
1
,
0
);
break
;
case
OPCODE_dup
:
type_stack_dup
(
1
,
0
);
break
;
case
OPCODE_dup_x1
:
type_stack_dup
(
1
,
1
);
break
;
case
OPCODE_dup_x1
:
type_stack_dup
(
1
,
1
);
break
;
...
@@ -934,7 +966,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -934,7 +966,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
i
=
TREE_INT_CST_LOW
(
get_constant
(
current_jcf
,
index
));
i
=
TREE_INT_CST_LOW
(
get_constant
(
current_jcf
,
index
));
goto
push_int
;
goto
push_int
;
}
}
push_type
(
type
);
PUSH_TYPE
(
type
);
break
;
break
;
case
OPCODE_invokevirtual
:
case
OPCODE_invokevirtual
:
...
@@ -953,7 +985,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -953,7 +985,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
IDENTIFIER_LENGTH
(
sig
));
IDENTIFIER_LENGTH
(
sig
));
if
(
TREE_CODE
(
method_type
)
!=
FUNCTION_TYPE
)
if
(
TREE_CODE
(
method_type
)
!=
FUNCTION_TYPE
)
VERIFICATION_ERROR
(
"bad method signature"
);
VERIFICATION_ERROR
(
"bad method signature"
);
pop_argument_types
(
TYPE_ARG_TYPES
(
method_type
));
pmessage
=
pop_argument_types
(
TYPE_ARG_TYPES
(
method_type
));
if
(
pmessage
!=
NULL
)
{
message
=
"invalid argument type"
;
goto
pop_type_error
;
}
/* Can't invoke <clinit> */
/* Can't invoke <clinit> */
if
(
ID_CLINIT_P
(
method_name
))
if
(
ID_CLINIT_P
(
method_name
))
...
@@ -963,7 +1000,8 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -963,7 +1000,8 @@ verify_jvm_instructions (jcf, byte_ops, length)
VERIFICATION_ERROR
(
"invoke opcode can't invoke <init>"
);
VERIFICATION_ERROR
(
"invoke opcode can't invoke <init>"
);
if
(
op_code
!=
OPCODE_invokestatic
)
if
(
op_code
!=
OPCODE_invokestatic
)
pop_type
(
self_type
);
POP_TYPE
(
self_type
,
"stack type not subclass of invoked method's class"
);
switch
(
op_code
)
switch
(
op_code
)
{
{
...
@@ -980,14 +1018,14 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -980,14 +1018,14 @@ verify_jvm_instructions (jcf, byte_ops, length)
}
}
if
(
TREE_TYPE
(
method_type
)
!=
void_type_node
)
if
(
TREE_TYPE
(
method_type
)
!=
void_type_node
)
push_type
(
TREE_TYPE
(
method_type
));
PUSH_TYPE
(
TREE_TYPE
(
method_type
));
break
;
break
;
}
}
case
OPCODE_arraylength
:
case
OPCODE_arraylength
:
/* Type checking actually made during code generation */
/* Type checking actually made during code generation */
pop_type
(
ptr_type_node
);
pop_type
(
ptr_type_node
);
push_type
(
int_type_node
);
PUSH_TYPE
(
int_type_node
);
break
;
break
;
/* Q&D verification *or* more checking done during code generation
/* Q&D verification *or* more checking done during code generation
...
@@ -1025,7 +1063,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -1025,7 +1063,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
type
=
TYPE_ARRAY_ELEMENT
(
TREE_TYPE
(
tmp
));
type
=
TYPE_ARRAY_ELEMENT
(
TREE_TYPE
(
tmp
));
else
if
(
tmp
!=
TYPE_NULL
)
else
if
(
tmp
!=
TYPE_NULL
)
VERIFICATION_ERROR
(
"array load from non-array type"
);
VERIFICATION_ERROR
(
"array load from non-array type"
);
push_type
(
type
);
PUSH_TYPE
(
type
);
break
;
break
;
case
OPCODE_anewarray
:
case
OPCODE_anewarray
:
...
@@ -1061,7 +1099,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -1061,7 +1099,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
int_value
=
-
1
;
int_value
=
-
1
;
type
=
build_java_array_type
(
type
,
int_value
);
type
=
build_java_array_type
(
type
,
int_value
);
pop_type
(
int_type_node
);
pop_type
(
int_type_node
);
push_type
(
type
);
PUSH_TYPE
(
type
);
break
;
break
;
case
OPCODE_multianewarray
:
case
OPCODE_multianewarray
:
...
@@ -1075,12 +1113,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -1075,12 +1113,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
for
(
i
=
0
;
i
<
ndim
;
i
++
)
for
(
i
=
0
;
i
<
ndim
;
i
++
)
pop_type
(
int_type_node
);
pop_type
(
int_type_node
);
push_type
(
get_class_constant
(
current_jcf
,
index
));
PUSH_TYPE
(
get_class_constant
(
current_jcf
,
index
));
break
;
break
;
}
}
case
OPCODE_aconst_null
:
case
OPCODE_aconst_null
:
push_type
(
ptr_type_node
);
PUSH_TYPE
(
ptr_type_node
);
break
;
break
;
case
OPCODE_athrow
:
case
OPCODE_athrow
:
...
@@ -1092,12 +1130,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -1092,12 +1130,12 @@ verify_jvm_instructions (jcf, byte_ops, length)
case
OPCODE_checkcast
:
case
OPCODE_checkcast
:
pop_type
(
ptr_type_node
);
pop_type
(
ptr_type_node
);
type
=
get_class_constant
(
current_jcf
,
IMMEDIATE_u2
);
type
=
get_class_constant
(
current_jcf
,
IMMEDIATE_u2
);
push_type
(
type
);
PUSH_TYPE
(
type
);
break
;
break
;
case
OPCODE_instanceof
:
case
OPCODE_instanceof
:
pop_type
(
ptr_type_node
);
pop_type
(
ptr_type_node
);
get_class_constant
(
current_jcf
,
IMMEDIATE_u2
);
get_class_constant
(
current_jcf
,
IMMEDIATE_u2
);
push_type
(
int_type_node
);
PUSH_TYPE
(
int_type_node
);
break
;
break
;
case
OPCODE_tableswitch
:
case
OPCODE_tableswitch
:
...
@@ -1170,7 +1208,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -1170,7 +1208,7 @@ verify_jvm_instructions (jcf, byte_ops, length)
{
{
tree
target
=
lookup_label
(
oldpc
+
IMMEDIATE_s2
);
tree
target
=
lookup_label
(
oldpc
+
IMMEDIATE_s2
);
tree
return_label
=
lookup_label
(
PC
);
tree
return_label
=
lookup_label
(
PC
);
push_type
(
return_address_type_node
);
PUSH_TYPE
(
return_address_type_node
);
/* The return label chain will be null if this is the first
/* The return label chain will be null if this is the first
time we've seen this jsr target. */
time we've seen this jsr target. */
if
(
LABEL_RETURN_LABEL
(
target
)
==
NULL_TREE
)
if
(
LABEL_RETURN_LABEL
(
target
)
==
NULL_TREE
)
...
@@ -1358,6 +1396,16 @@ verify_jvm_instructions (jcf, byte_ops, length)
...
@@ -1358,6 +1396,16 @@ verify_jvm_instructions (jcf, byte_ops, length)
}
}
}
}
return
1
;
return
1
;
pop_type_error
:
error
(
"verification error at PC=%d"
,
oldpc
);
if
(
message
!=
NULL
)
error
(
"%s"
,
message
);
error
(
"%s"
,
pmessage
);
free
(
pmessage
);
return
0
;
stack_overflow
:
message
=
"stack overflow"
;
goto
verify_error
;
bad_pc
:
bad_pc
:
message
=
"program counter out of range"
;
message
=
"program counter out of range"
;
goto
verify_error
;
goto
verify_error
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment