< prev index next >

src/hotspot/share/classfile/verifier.cpp

Print this page




 557     address end_of_sm_table = (address)sm_table + method->stackmap_data()->length();
 558     for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
 559       ss->indent();
 560       if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) {
 561         sm_frame->print_truncated(ss, current_offset);
 562         return;
 563       }
 564       sm_frame->print_on(ss, current_offset);
 565       ss->cr();
 566       current_offset += sm_frame->offset_delta();
 567       sm_frame = sm_frame->next();
 568     }
 569   }
 570 }
 571 
 572 // Methods in ClassVerifier
 573 
 574 ClassVerifier::ClassVerifier(
 575     InstanceKlass* klass, TRAPS)
 576     : _thread(THREAD), _previous_symbol(NULL), _symbols(NULL), _exception_type(NULL),
 577       _message(NULL), _klass(klass) {
 578   _this_type = VerificationType::reference_type(klass->name());
 579 }
 580 
 581 ClassVerifier::~ClassVerifier() {
 582   // Decrement the reference count for any symbols created.
 583   if (_symbols != NULL) {
 584     for (int i = 0; i < _symbols->length(); i++) {
 585       Symbol* s = _symbols->at(i);
 586       s->decrement_refcount();
 587     }
 588   }
 589 }
 590 
 591 VerificationType ClassVerifier::object_type() const {
 592   return VerificationType::reference_type(vmSymbols::java_lang_Object());
 593 }
 594 
 595 TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) {
 596   VerificationType vt = VerificationType::reference_type(
 597       create_temporary_symbol(sig, (int)strlen(sig), THREAD));
 598   return TypeOrigin::implicit(vt);
 599 }
 600 
 601 void ClassVerifier::verify_class(TRAPS) {
 602   log_info(verification)("Verifying class %s with new format", _klass->external_name());
 603 







 604   Array<Method*>* methods = _klass->methods();
 605   int num_methods = methods->length();
 606 
 607   for (int index = 0; index < num_methods; index++) {
 608     // Check for recursive re-verification before each method.
 609     if (was_recursively_verified())  return;
 610 
 611     Method* m = methods->at(index);
 612     if (m->is_native() || m->is_abstract() || m->is_overpass()) {
 613       // If m is native or abstract, skip it.  It is checked in class file
 614       // parser that methods do not override a final method.  Overpass methods
 615       // are trusted since the VM generates them.
 616       continue;
 617     }
 618     verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
 619   }
 620 
 621   if (was_recursively_verified()){
 622     log_info(verification)("Recursive verification detected for: %s", _klass->external_name());
 623     log_info(class, init)("Recursive verification detected for: %s",
 624                         _klass->external_name());
 625   }
 626 }
 627 

















































 628 void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
 629   HandleMark hm(THREAD);
 630   _method = m;   // initialize _method
 631   log_info(verification)("Verifying method %s", m->name_and_sig_as_C_string());
 632 
 633 // For clang, the only good constant format string is a literal constant format string.
 634 #define bad_type_msg "Bad type on operand stack in %s"
 635 
 636   int32_t max_stack = m->verifier_max_stack();
 637   int32_t max_locals = m->max_locals();
 638   constantPoolHandle cp(THREAD, m->constants());
 639 
 640   // Method signature was checked in ClassFileParser.
 641   assert(SignatureVerifier::is_valid_method_signature(m->signature()),
 642          "Invalid method signature");
 643 
 644   // Initial stack map frame: offset is 0, stack is initially empty.
 645   StackMapFrame current_frame(max_locals, max_stack, this);
 646   // Set initial locals
 647   VerificationType return_type = current_frame.set_locals_from_arg(


2717   Symbol* method_name = cp->name_ref_at(index);
2718   Symbol* method_sig = cp->signature_ref_at(index);
2719 
2720   // Method signature was checked in ClassFileParser.
2721   assert(SignatureVerifier::is_valid_method_signature(method_sig),
2722          "Invalid method signature");
2723 
2724   // Get referenced class type
2725   VerificationType ref_class_type;
2726   if (opcode == Bytecodes::_invokedynamic) {
2727     if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
2728       class_format_error(
2729         "invokedynamic instructions not supported by this class file version (%d), class %s",
2730         _klass->major_version(), _klass->external_name());
2731       return;
2732     }
2733   } else {
2734     ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this));
2735   }
2736 
2737   // For a small signature length, we just allocate 128 bytes instead
2738   // of parsing the signature once to find its size.
2739   // -3 is for '(', ')' and return descriptor; multiply by 2 is for
2740   // longs/doubles to be consertive.
2741   assert(sizeof(VerificationType) == sizeof(uintptr_t),
2742         "buffer type must match VerificationType size");
2743   uintptr_t on_stack_sig_types_buffer[128];
2744   // If we make a VerificationType[128] array directly, the compiler calls
2745   // to the c-runtime library to do the allocation instead of just
2746   // stack allocating it.  Plus it would run constructors.  This shows up
2747   // in performance profiles.
2748 
2749   VerificationType* sig_types;
2750   int size = (method_sig->utf8_length() - 3) * 2;
2751   if (size > 128) {
2752     // Long and double occupies two slots here.
2753     ArgumentSizeComputer size_it(method_sig);
2754     size = size_it.size();
2755     sig_types = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, VerificationType, size);
2756   } else{
2757     sig_types = (VerificationType*)on_stack_sig_types_buffer;
2758   }
2759   SignatureStream sig_stream(method_sig);
2760   int sig_i = 0;
2761   while (!sig_stream.at_return_type()) {
2762     sig_i += change_sig_to_verificationType(
2763       &sig_stream, &sig_types[sig_i], CHECK_VERIFY(this));
2764     sig_stream.next();
2765   }
2766   int nargs = sig_i;
2767 
2768 #ifdef ASSERT
2769   {
2770     ArgumentSizeComputer size_it(method_sig);
2771     assert(nargs == size_it.size(), "Argument sizes do not match");
2772     assert(nargs <= (method_sig->utf8_length() - 3) * 2, "estimate of max size isn't conservative enough");







2773   }
2774 #endif


2775 
2776   // Check instruction operands
2777   u2 bci = bcs->bci();
2778   if (opcode == Bytecodes::_invokeinterface) {
2779     address bcp = bcs->bcp();
2780     // 4905268: count operand in invokeinterface should be nargs+1, not nargs.
2781     // JSR202 spec: The count operand of an invokeinterface instruction is valid if it is
2782     // the difference between the size of the operand stack before and after the instruction
2783     // executes.
2784     if (*(bcp+3) != (nargs+1)) {
2785       verify_error(ErrorContext::bad_code(bci),
2786           "Inconsistent args count operand in invokeinterface");
2787       return;
2788     }
2789     if (*(bcp+4) != 0) {
2790       verify_error(ErrorContext::bad_code(bci),
2791           "Fourth operand byte of invokeinterface must be zero");
2792       return;
2793     }
2794   }


2827       // If invokespecial of IMR, need to recheck for same or
2828       // direct interface relative to the host class
2829       have_imr_indirect = (have_imr_indirect &&
2830                            !is_same_or_direct_interface(
2831                              current_class()->unsafe_anonymous_host(),
2832                              unsafe_anonymous_host_type, ref_class_type));
2833     }
2834     if (!subtype) {
2835       verify_error(ErrorContext::bad_code(bci),
2836           "Bad invokespecial instruction: "
2837           "current class isn't assignable to reference class.");
2838        return;
2839     } else if (have_imr_indirect) {
2840       verify_error(ErrorContext::bad_code(bci),
2841           "Bad invokespecial instruction: "
2842           "interface method reference is in an indirect superinterface.");
2843       return;
2844     }
2845 
2846   }




2847   // Match method descriptor with operand stack

2848   for (int i = nargs - 1; i >= 0; i--) {  // Run backwards
2849     current_frame->pop_stack(sig_types[i], CHECK_VERIFY(this));
2850   }

2851   // Check objectref on operand stack
2852   if (opcode != Bytecodes::_invokestatic &&
2853       opcode != Bytecodes::_invokedynamic) {
2854     if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
2855       verify_invoke_init(bcs, index, ref_class_type, current_frame,
2856         code_length, in_try_block, this_uninit, cp, stackmap_table,
2857         CHECK_VERIFY(this));
2858       if (was_recursively_verified()) return;
2859     } else {   // other methods
2860       // Ensures that target class is assignable to method class.
2861       if (opcode == Bytecodes::_invokespecial) {
2862         if (!current_class()->is_unsafe_anonymous()) {
2863           current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
2864         } else {
2865           // anonymous class invokespecial calls: check if the
2866           // objectref is a subtype of the unsafe_anonymous_host of the current class
2867           // to allow an anonymous class to reference methods in the unsafe_anonymous_host
2868           VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
2869           VerificationType hosttype =
2870             VerificationType::reference_type(current_class()->unsafe_anonymous_host()->name());


2902                   // Special case: arrays pretend to implement public Object
2903                   // clone().
2904                 } else {
2905                   verify_error(ErrorContext::bad_type(bci,
2906                       current_frame->stack_top_ctx(),
2907                       TypeOrigin::implicit(current_type())),
2908                       "Bad access to protected data in invokevirtual");
2909                   return;
2910                 }
2911               }
2912             }
2913           }
2914         }
2915       } else {
2916         assert(opcode == Bytecodes::_invokeinterface, "Unexpected opcode encountered");
2917         current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
2918       }
2919     }
2920   }
2921   // Push the result type.
2922   if (sig_stream.type() != T_VOID) {

2923     if (method_name == vmSymbols::object_initializer_name()) {
2924       // <init> method must have a void return type
2925       /* Unreachable?  Class file parser verifies that methods with '<' have
2926        * void return */
2927       verify_error(ErrorContext::bad_code(bci),
2928           "Return type must be void in <init> method");
2929       return;
2930     }
2931     VerificationType return_type[2];
2932     int n = change_sig_to_verificationType(
2933       &sig_stream, return_type, CHECK_VERIFY(this));
2934     for (int i = 0; i < n; i++) {
2935       current_frame->push_stack(return_type[i], CHECK_VERIFY(this)); // push types backwards


2936     }
2937   }
2938 }
2939 
2940 VerificationType ClassVerifier::get_newarray_type(
2941     u2 index, u2 bci, TRAPS) {
2942   const char* from_bt[] = {
2943     NULL, NULL, NULL, NULL, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J",
2944   };
2945   if (index < T_BOOLEAN || index > T_LONG) {
2946     verify_error(ErrorContext::bad_code(bci), "Illegal newarray instruction");
2947     return VerificationType::bogus_type();
2948   }
2949 
2950   // from_bt[index] contains the array signature which has a length of 2
2951   Symbol* sig = create_temporary_symbol(
2952     from_bt[index], 2, CHECK_(VerificationType::bogus_type()));
2953   return VerificationType::reference_type(sig);
2954 }
2955 




 557     address end_of_sm_table = (address)sm_table + method->stackmap_data()->length();
 558     for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
 559       ss->indent();
 560       if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) {
 561         sm_frame->print_truncated(ss, current_offset);
 562         return;
 563       }
 564       sm_frame->print_on(ss, current_offset);
 565       ss->cr();
 566       current_offset += sm_frame->offset_delta();
 567       sm_frame = sm_frame->next();
 568     }
 569   }
 570 }
 571 
 572 // Methods in ClassVerifier
 573 
 574 ClassVerifier::ClassVerifier(
 575     InstanceKlass* klass, TRAPS)
 576     : _thread(THREAD), _previous_symbol(NULL), _symbols(NULL), _exception_type(NULL),
 577       _message(NULL), _method_signatures_table(NULL), _klass(klass) {
 578   _this_type = VerificationType::reference_type(klass->name());
 579 }
 580 
 581 ClassVerifier::~ClassVerifier() {
 582   // Decrement the reference count for any symbols created.
 583   if (_symbols != NULL) {
 584     for (int i = 0; i < _symbols->length(); i++) {
 585       Symbol* s = _symbols->at(i);
 586       s->decrement_refcount();
 587     }
 588   }
 589 }
 590 
 591 VerificationType ClassVerifier::object_type() const {
 592   return VerificationType::reference_type(vmSymbols::java_lang_Object());
 593 }
 594 
 595 TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) {
 596   VerificationType vt = VerificationType::reference_type(
 597       create_temporary_symbol(sig, (int)strlen(sig), THREAD));
 598   return TypeOrigin::implicit(vt);
 599 }
 600 
 601 void ClassVerifier::verify_class(TRAPS) {
 602   log_info(verification)("Verifying class %s with new format", _klass->external_name());
 603 
 604   // Either verifying both local and remote classes or just remote classes.
 605   assert(BytecodeVerificationRemote, "Should not be here");
 606 
 607   // Create hash table containing method signatures.
 608   method_signatures_table_type method_signatures_table;
 609   set_method_signatures_table(&method_signatures_table);
 610 
 611   Array<Method*>* methods = _klass->methods();
 612   int num_methods = methods->length();
 613 
 614   for (int index = 0; index < num_methods; index++) {
 615     // Check for recursive re-verification before each method.
 616     if (was_recursively_verified())  return;
 617 
 618     Method* m = methods->at(index);
 619     if (m->is_native() || m->is_abstract() || m->is_overpass()) {
 620       // If m is native or abstract, skip it.  It is checked in class file
 621       // parser that methods do not override a final method.  Overpass methods
 622       // are trusted since the VM generates them.
 623       continue;
 624     }
 625     verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
 626   }
 627 
 628   if (was_recursively_verified()){
 629     log_info(verification)("Recursive verification detected for: %s", _klass->external_name());
 630     log_info(class, init)("Recursive verification detected for: %s",
 631                         _klass->external_name());
 632   }
 633 }
 634 
 635 // Translate the signature entries into verification types and save them in
 636 // the growable array.  Also, save the count of arguments.
 637 void ClassVerifier::translate_signature(Symbol* const method_sig,
 638                                         sig_as_verification_types* sig_verif_types,
 639                                         TRAPS) {
 640   SignatureStream sig_stream(method_sig);
 641   VerificationType sig_type[2];
 642   int sig_i = 0;
 643   GrowableArray<VerificationType>* verif_types = sig_verif_types->sig_verif_types();
 644 
 645   // Translate the signature arguments into verification types.
 646   while (!sig_stream.at_return_type()) {
 647     int n = change_sig_to_verificationType(&sig_stream, sig_type, CHECK_VERIFY(this));
 648     assert(n <= 2, "Unexpected signature type");
 649 
 650     // Store verification type(s).  Longs and Doubles each have two verificationTypes.
 651     for (int x = 0; x < n; x++) {
 652       verif_types->push(sig_type[x]);
 653     }
 654     sig_i += n;
 655     sig_stream.next();
 656   }
 657 
 658   // Set final arg count, not including the return type.  The final arg count will
 659   // be compared with sig_verify_types' length to see if there is a return type.
 660   sig_verif_types->set_num_args(sig_i);
 661 
 662   // Store verification type(s) for the return type, if there is one.
 663   if (sig_stream.type() != T_VOID) {
 664     int n = change_sig_to_verificationType(&sig_stream, sig_type, CHECK_VERIFY(this));
 665     assert(n <= 2, "Unexpected signature return type");
 666     for (int y = 0; y < n; y++) {
 667       verif_types->push(sig_type[y]);
 668     }
 669   }
 670 }
 671 
 672 void ClassVerifier::create_method_sig_entry(sig_as_verification_types* sig_verif_types,
 673                                             int sig_index, TRAPS) {
 674   // Translate the signature into verification types.
 675   ConstantPool* cp = _klass->constants();
 676   Symbol* const method_sig = cp->symbol_at(sig_index);
 677   translate_signature(method_sig, sig_verif_types, CHECK_VERIFY(this));
 678 
 679   // Add the list of this signature's verification types to the table.
 680   bool is_unique = method_signatures_table()->put(sig_index, sig_verif_types);
 681   assert(is_unique, "Duplicate entries in method_signature_table");
 682 }
 683 
 684 void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
 685   HandleMark hm(THREAD);
 686   _method = m;   // initialize _method
 687   log_info(verification)("Verifying method %s", m->name_and_sig_as_C_string());
 688 
 689 // For clang, the only good constant format string is a literal constant format string.
 690 #define bad_type_msg "Bad type on operand stack in %s"
 691 
 692   int32_t max_stack = m->verifier_max_stack();
 693   int32_t max_locals = m->max_locals();
 694   constantPoolHandle cp(THREAD, m->constants());
 695 
 696   // Method signature was checked in ClassFileParser.
 697   assert(SignatureVerifier::is_valid_method_signature(m->signature()),
 698          "Invalid method signature");
 699 
 700   // Initial stack map frame: offset is 0, stack is initially empty.
 701   StackMapFrame current_frame(max_locals, max_stack, this);
 702   // Set initial locals
 703   VerificationType return_type = current_frame.set_locals_from_arg(


2773   Symbol* method_name = cp->name_ref_at(index);
2774   Symbol* method_sig = cp->signature_ref_at(index);
2775 
2776   // Method signature was checked in ClassFileParser.
2777   assert(SignatureVerifier::is_valid_method_signature(method_sig),
2778          "Invalid method signature");
2779 
2780   // Get referenced class type
2781   VerificationType ref_class_type;
2782   if (opcode == Bytecodes::_invokedynamic) {
2783     if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
2784       class_format_error(
2785         "invokedynamic instructions not supported by this class file version (%d), class %s",
2786         _klass->major_version(), _klass->external_name());
2787       return;
2788     }
2789   } else {
2790     ref_class_type = cp_ref_index_to_type(index, cp, CHECK_VERIFY(this));
2791   }
2792 




2793   assert(sizeof(VerificationType) == sizeof(uintptr_t),
2794         "buffer type must match VerificationType size");





2795 
2796   // Get the UTF8 index for this signature.
2797   int sig_index = cp->signature_ref_index_at(cp->name_and_type_ref_index_at(index));
















2798 
2799   // Get the signature's verification types.
2800   sig_as_verification_types* mth_sig_verif_types;
2801   sig_as_verification_types** mth_sig_verif_types_ptr = method_signatures_table()->get(sig_index);
2802   if (mth_sig_verif_types_ptr != NULL) {
2803     // Found the entry for the signature's verification types in the hash table.
2804     mth_sig_verif_types = *mth_sig_verif_types_ptr;
2805     assert(mth_sig_verif_types != NULL, "Unexpected NULL sig_as_verification_types value");
2806   } else {
2807     // Not found, add the entry to the table.
2808     GrowableArray<VerificationType>* verif_types = new GrowableArray<VerificationType>(10);
2809     mth_sig_verif_types = new sig_as_verification_types(verif_types);
2810     create_method_sig_entry(mth_sig_verif_types, sig_index, CHECK_VERIFY(this));
2811   }
2812 
2813   // Get the number of arguments for this signature.
2814   int nargs = mth_sig_verif_types->num_args();
2815 
2816   // Check instruction operands
2817   u2 bci = bcs->bci();
2818   if (opcode == Bytecodes::_invokeinterface) {
2819     address bcp = bcs->bcp();
2820     // 4905268: count operand in invokeinterface should be nargs+1, not nargs.
2821     // JSR202 spec: The count operand of an invokeinterface instruction is valid if it is
2822     // the difference between the size of the operand stack before and after the instruction
2823     // executes.
2824     if (*(bcp+3) != (nargs+1)) {
2825       verify_error(ErrorContext::bad_code(bci),
2826           "Inconsistent args count operand in invokeinterface");
2827       return;
2828     }
2829     if (*(bcp+4) != 0) {
2830       verify_error(ErrorContext::bad_code(bci),
2831           "Fourth operand byte of invokeinterface must be zero");
2832       return;
2833     }
2834   }


2867       // If invokespecial of IMR, need to recheck for same or
2868       // direct interface relative to the host class
2869       have_imr_indirect = (have_imr_indirect &&
2870                            !is_same_or_direct_interface(
2871                              current_class()->unsafe_anonymous_host(),
2872                              unsafe_anonymous_host_type, ref_class_type));
2873     }
2874     if (!subtype) {
2875       verify_error(ErrorContext::bad_code(bci),
2876           "Bad invokespecial instruction: "
2877           "current class isn't assignable to reference class.");
2878        return;
2879     } else if (have_imr_indirect) {
2880       verify_error(ErrorContext::bad_code(bci),
2881           "Bad invokespecial instruction: "
2882           "interface method reference is in an indirect superinterface.");
2883       return;
2884     }
2885 
2886   }
2887 
2888   // Get the verification types for the method's arguments.
2889   GrowableArray<VerificationType>* sig_verif_types = mth_sig_verif_types->sig_verif_types();
2890   assert(sig_verif_types != NULL, "Missing signature's array of verification types");
2891   // Match method descriptor with operand stack
2892   // The arguments are on the stack in descending order.
2893   for (int i = nargs - 1; i >= 0; i--) { // Run backwards
2894     current_frame->pop_stack(sig_verif_types->at(i), CHECK_VERIFY(this));
2895   }
2896 
2897   // Check objectref on operand stack
2898   if (opcode != Bytecodes::_invokestatic &&
2899       opcode != Bytecodes::_invokedynamic) {
2900     if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
2901       verify_invoke_init(bcs, index, ref_class_type, current_frame,
2902         code_length, in_try_block, this_uninit, cp, stackmap_table,
2903         CHECK_VERIFY(this));
2904       if (was_recursively_verified()) return;
2905     } else {   // other methods
2906       // Ensures that target class is assignable to method class.
2907       if (opcode == Bytecodes::_invokespecial) {
2908         if (!current_class()->is_unsafe_anonymous()) {
2909           current_frame->pop_stack(current_type(), CHECK_VERIFY(this));
2910         } else {
2911           // anonymous class invokespecial calls: check if the
2912           // objectref is a subtype of the unsafe_anonymous_host of the current class
2913           // to allow an anonymous class to reference methods in the unsafe_anonymous_host
2914           VerificationType top = current_frame->pop_stack(CHECK_VERIFY(this));
2915           VerificationType hosttype =
2916             VerificationType::reference_type(current_class()->unsafe_anonymous_host()->name());


2948                   // Special case: arrays pretend to implement public Object
2949                   // clone().
2950                 } else {
2951                   verify_error(ErrorContext::bad_type(bci,
2952                       current_frame->stack_top_ctx(),
2953                       TypeOrigin::implicit(current_type())),
2954                       "Bad access to protected data in invokevirtual");
2955                   return;
2956                 }
2957               }
2958             }
2959           }
2960         }
2961       } else {
2962         assert(opcode == Bytecodes::_invokeinterface, "Unexpected opcode encountered");
2963         current_frame->pop_stack(ref_class_type, CHECK_VERIFY(this));
2964       }
2965     }
2966   }
2967   // Push the result type.
2968   int sig_verif_types_len = sig_verif_types->length();
2969   if (sig_verif_types_len > nargs) {  // There's a return type
2970     if (method_name == vmSymbols::object_initializer_name()) {
2971       // <init> method must have a void return type
2972       /* Unreachable?  Class file parser verifies that methods with '<' have
2973        * void return */
2974       verify_error(ErrorContext::bad_code(bci),
2975           "Return type must be void in <init> method");
2976       return;
2977     }
2978 
2979     assert(sig_verif_types_len <= nargs + 2,
2980            "Signature verification types array return type is bogus");
2981     for (int i = nargs; i < sig_verif_types_len; i++) {
2982       assert(i == nargs || sig_verif_types->at(i).is_long2() ||
2983              sig_verif_types->at(i).is_double2(), "Unexpected return verificationType");
2984       current_frame->push_stack(sig_verif_types->at(i), CHECK_VERIFY(this));
2985     }
2986   }
2987 }
2988 
2989 VerificationType ClassVerifier::get_newarray_type(
2990     u2 index, u2 bci, TRAPS) {
2991   const char* from_bt[] = {
2992     NULL, NULL, NULL, NULL, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J",
2993   };
2994   if (index < T_BOOLEAN || index > T_LONG) {
2995     verify_error(ErrorContext::bad_code(bci), "Illegal newarray instruction");
2996     return VerificationType::bogus_type();
2997   }
2998 
2999   // from_bt[index] contains the array signature which has a length of 2
3000   Symbol* sig = create_temporary_symbol(
3001     from_bt[index], 2, CHECK_(VerificationType::bogus_type()));
3002   return VerificationType::reference_type(sig);
3003 }
3004 


< prev index next >