206 } |
206 } |
207 |
207 |
208 return true; |
208 return true; |
209 } |
209 } |
210 |
210 |
211 bool StackMapFrame::is_assignable_to(const StackMapFrame* target, TRAPS) const { |
211 bool StackMapFrame::is_assignable_to( |
212 if (_max_locals != target->max_locals() || _stack_size != target->stack_size()) { |
212 const StackMapFrame* target, bool is_exception_handler, TRAPS) const { |
|
213 if (_max_locals != target->max_locals() || |
|
214 _stack_size != target->stack_size()) { |
213 return false; |
215 return false; |
214 } |
216 } |
215 // Only need to compare type elements up to target->locals() or target->stack(). |
217 // Only need to compare type elements up to target->locals() or target->stack(). |
216 // The remaining type elements in this state can be ignored because they are |
218 // The remaining type elements in this state can be ignored because they are |
217 // assignable to bogus type. |
219 // assignable to bogus type. |
220 bool match_stack = is_assignable_to( |
222 bool match_stack = is_assignable_to( |
221 _stack, target->stack(), _stack_size, CHECK_false); |
223 _stack, target->stack(), _stack_size, CHECK_false); |
222 bool match_flags = (_flags | target->flags()) == target->flags(); |
224 bool match_flags = (_flags | target->flags()) == target->flags(); |
223 |
225 |
224 return match_locals && match_stack && |
226 return match_locals && match_stack && |
225 (match_flags || has_flag_match_exception(target)); |
227 (match_flags || (is_exception_handler && has_flag_match_exception(target))); |
226 } |
228 } |
227 |
229 |
228 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) { |
230 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) { |
229 if (_stack_size <= 0) { |
231 if (_stack_size <= 0) { |
230 verifier()->verify_error(_offset, "Operand stack underflow"); |
232 verifier()->verify_error(_offset, "Operand stack underflow"); |