1366 |
1366 |
1367 return code_data; |
1367 return code_data; |
1368 } |
1368 } |
1369 |
1369 |
1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) { |
1370 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) { |
1371 typeArrayHandle exhandlers (THREAD, _method->exception_table()); |
1371 ExceptionTable exhandlers(_method()); |
|
1372 int exlength = exhandlers.length(); |
1372 constantPoolHandle cp (THREAD, _method->constants()); |
1373 constantPoolHandle cp (THREAD, _method->constants()); |
1373 |
1374 |
1374 if (exhandlers() != NULL) { |
1375 for(int i = 0; i < exlength; i++) { |
1375 for(int i = 0; i < exhandlers->length();) { |
1376 //reacquire the table in case a GC happened |
1376 u2 start_pc = exhandlers->int_at(i++); |
1377 ExceptionTable exhandlers(_method()); |
1377 u2 end_pc = exhandlers->int_at(i++); |
1378 u2 start_pc = exhandlers.start_pc(i); |
1378 u2 handler_pc = exhandlers->int_at(i++); |
1379 u2 end_pc = exhandlers.end_pc(i); |
1379 if (start_pc >= code_length || code_data[start_pc] == 0) { |
1380 u2 handler_pc = exhandlers.handler_pc(i); |
1380 class_format_error("Illegal exception table start_pc %d", start_pc); |
1381 if (start_pc >= code_length || code_data[start_pc] == 0) { |
|
1382 class_format_error("Illegal exception table start_pc %d", start_pc); |
|
1383 return; |
|
1384 } |
|
1385 if (end_pc != code_length) { // special case: end_pc == code_length |
|
1386 if (end_pc > code_length || code_data[end_pc] == 0) { |
|
1387 class_format_error("Illegal exception table end_pc %d", end_pc); |
1381 return; |
1388 return; |
1382 } |
1389 } |
1383 if (end_pc != code_length) { // special case: end_pc == code_length |
1390 } |
1384 if (end_pc > code_length || code_data[end_pc] == 0) { |
1391 if (handler_pc >= code_length || code_data[handler_pc] == 0) { |
1385 class_format_error("Illegal exception table end_pc %d", end_pc); |
1392 class_format_error("Illegal exception table handler_pc %d", handler_pc); |
1386 return; |
1393 return; |
1387 } |
1394 } |
1388 } |
1395 int catch_type_index = exhandlers.catch_type_index(i); |
1389 if (handler_pc >= code_length || code_data[handler_pc] == 0) { |
1396 if (catch_type_index != 0) { |
1390 class_format_error("Illegal exception table handler_pc %d", handler_pc); |
1397 VerificationType catch_type = cp_index_to_type( |
|
1398 catch_type_index, cp, CHECK_VERIFY(this)); |
|
1399 VerificationType throwable = |
|
1400 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); |
|
1401 bool is_subclass = throwable.is_assignable_from( |
|
1402 catch_type, this, CHECK_VERIFY(this)); |
|
1403 if (!is_subclass) { |
|
1404 // 4286534: should throw VerifyError according to recent spec change |
|
1405 verify_error( |
|
1406 "Catch type is not a subclass of Throwable in handler %d", |
|
1407 handler_pc); |
1391 return; |
1408 return; |
1392 } |
1409 } |
1393 int catch_type_index = exhandlers->int_at(i++); |
1410 } |
1394 if (catch_type_index != 0) { |
1411 if (start_pc < min) min = start_pc; |
1395 VerificationType catch_type = cp_index_to_type( |
1412 if (end_pc > max) max = end_pc; |
1396 catch_type_index, cp, CHECK_VERIFY(this)); |
|
1397 VerificationType throwable = |
|
1398 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); |
|
1399 bool is_subclass = throwable.is_assignable_from( |
|
1400 catch_type, this, CHECK_VERIFY(this)); |
|
1401 if (!is_subclass) { |
|
1402 // 4286534: should throw VerifyError according to recent spec change |
|
1403 verify_error( |
|
1404 "Catch type is not a subclass of Throwable in handler %d", |
|
1405 handler_pc); |
|
1406 return; |
|
1407 } |
|
1408 } |
|
1409 if (start_pc < min) min = start_pc; |
|
1410 if (end_pc > max) max = end_pc; |
|
1411 } |
|
1412 } |
1413 } |
1413 } |
1414 } |
1414 |
1415 |
1415 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) { |
1416 void ClassVerifier::verify_local_variable_table(u4 code_length, char* code_data, TRAPS) { |
1416 int localvariable_table_length = _method()->localvariable_table_length(); |
1417 int localvariable_table_length = _method()->localvariable_table_length(); |
1472 } |
1473 } |
1473 |
1474 |
1474 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame, |
1475 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame, |
1475 StackMapTable* stackmap_table, TRAPS) { |
1476 StackMapTable* stackmap_table, TRAPS) { |
1476 constantPoolHandle cp (THREAD, _method->constants()); |
1477 constantPoolHandle cp (THREAD, _method->constants()); |
1477 typeArrayHandle exhandlers (THREAD, _method->exception_table()); |
1478 ExceptionTable exhandlers(_method()); |
1478 if (exhandlers() != NULL) { |
1479 int exlength = exhandlers.length(); |
1479 for(int i = 0; i < exhandlers->length();) { |
1480 for(int i = 0; i < exlength; i++) { |
1480 u2 start_pc = exhandlers->int_at(i++); |
1481 //reacquire the table in case a GC happened |
1481 u2 end_pc = exhandlers->int_at(i++); |
1482 ExceptionTable exhandlers(_method()); |
1482 u2 handler_pc = exhandlers->int_at(i++); |
1483 u2 start_pc = exhandlers.start_pc(i); |
1483 int catch_type_index = exhandlers->int_at(i++); |
1484 u2 end_pc = exhandlers.end_pc(i); |
1484 if(bci >= start_pc && bci < end_pc) { |
1485 u2 handler_pc = exhandlers.handler_pc(i); |
1485 u1 flags = current_frame->flags(); |
1486 int catch_type_index = exhandlers.catch_type_index(i); |
1486 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } |
1487 if(bci >= start_pc && bci < end_pc) { |
1487 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); |
1488 u1 flags = current_frame->flags(); |
1488 if (catch_type_index != 0) { |
1489 if (this_uninit) { flags |= FLAG_THIS_UNINIT; } |
1489 // We know that this index refers to a subclass of Throwable |
1490 StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags); |
1490 VerificationType catch_type = cp_index_to_type( |
1491 if (catch_type_index != 0) { |
1491 catch_type_index, cp, CHECK_VERIFY(this)); |
1492 // We know that this index refers to a subclass of Throwable |
1492 new_frame->push_stack(catch_type, CHECK_VERIFY(this)); |
1493 VerificationType catch_type = cp_index_to_type( |
1493 } else { |
1494 catch_type_index, cp, CHECK_VERIFY(this)); |
1494 VerificationType throwable = |
1495 new_frame->push_stack(catch_type, CHECK_VERIFY(this)); |
1495 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); |
1496 } else { |
1496 new_frame->push_stack(throwable, CHECK_VERIFY(this)); |
1497 VerificationType throwable = |
1497 } |
1498 VerificationType::reference_type(vmSymbols::java_lang_Throwable()); |
1498 bool match = stackmap_table->match_stackmap( |
1499 new_frame->push_stack(throwable, CHECK_VERIFY(this)); |
1499 new_frame, handler_pc, true, false, CHECK_VERIFY(this)); |
1500 } |
1500 if (!match) { |
1501 bool match = stackmap_table->match_stackmap( |
1501 verify_error(bci, |
1502 new_frame, handler_pc, true, false, CHECK_VERIFY(this)); |
1502 "Stack map does not match the one at exception handler %d", |
1503 if (!match) { |
1503 handler_pc); |
1504 verify_error(bci, |
1504 return; |
1505 "Stack map does not match the one at exception handler %d", |
1505 } |
1506 handler_pc); |
|
1507 return; |
1506 } |
1508 } |
1507 } |
1509 } |
1508 } |
1510 } |
1509 } |
1511 } |
1510 |
1512 |