products/Sources/formale Sprachen/Java/openjdk-20-36_src/src/hotspot/share/classfile image not shown  

Quellcode-Bibliothek

© Kompilation durch diese Firma

[Weder Korrektheit noch Funktionsfähigkeit der Software werden zugesichert.]

Datei:   Sprache: C

/*
 * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */


#include "precompiled.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/stackMapTable.hpp"
#include "classfile/stackMapFrame.hpp"
#include "classfile/stackMapTableFormat.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "interpreter/bytecodes.hpp"
#include "interpreter/bytecodeStream.hpp"
#include "jvm.h"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/klass.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/typeArrayOop.hpp"
#include "runtime/arguments.hpp"
#include "runtime/fieldDescriptor.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/javaThread.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "services/threadService.hpp"
#include "utilities/align.hpp"
#include "utilities/bytes.hpp"

#define NOFAILOVER_MAJOR_VERSION                       51
#define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION  51
#define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION       52
#define MAX_ARRAY_DIMENSIONS 255

// Access to external entry for VerifyClassForMajorVersion - old byte code verifier

extern "C" {
  typedef jboolean (*verify_byte_codes_fn_t)(JNIEnv *, jclass, char *, jint, jint);
}

static verify_byte_codes_fn_t volatile _verify_byte_codes_fn = NULL;

static verify_byte_codes_fn_t verify_byte_codes_fn() {

  if (_verify_byte_codes_fn != NULL)
    return _verify_byte_codes_fn;

  MutexLocker locker(Verify_lock);

  if (_verify_byte_codes_fn != NULL)
    return _verify_byte_codes_fn;

  // Load verify dll
  char buffer[JVM_MAXPATHLEN];
  char ebuf[1024];
  if (!os::dll_locate_lib(buffer, sizeof(buffer), Arguments::get_dll_dir(), "verify"))
    return NULL; // Caller will throw VerifyError

  void *lib_handle = os::dll_load(buffer, ebuf, sizeof(ebuf));
  if (lib_handle == NULL)
    return NULL; // Caller will throw VerifyError

  void *fn = os::dll_lookup(lib_handle, "VerifyClassForMajorVersion");
  if (fn == NULL)
    return NULL; // Caller will throw VerifyError

  return _verify_byte_codes_fn = CAST_TO_FN_PTR(verify_byte_codes_fn_t, fn);
}


// Methods in Verifier

bool Verifier::should_verify_for(oop class_loader, bool should_verify_class) {
  return (class_loader == NULL || !should_verify_class) ?
    BytecodeVerificationLocal : BytecodeVerificationRemote;
}

bool Verifier::relax_access_for(oop loader) {
  bool trusted = java_lang_ClassLoader::is_trusted_loader(loader);
  bool need_verify =
    // verifyAll
    (BytecodeVerificationLocal && BytecodeVerificationRemote) ||
    // verifyRemote
    (!BytecodeVerificationLocal && BytecodeVerificationRemote && !trusted);
  return !need_verify;
}

void Verifier::trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class) {
  assert(verify_class != NULL, "Unexpected null verify_class");
  ResourceMark rm;
  Symbol* s = verify_class->source_file_name();
  const char* source_file = (s != NULL ? s->as_C_string() : NULL);
  const char* verify = verify_class->external_name();
  const char* resolve = resolve_class->external_name();
  // print in a single call to reduce interleaving between threads
  if (source_file != NULL) {
    log_debug(class, resolve)("%s %s %s (verification)", verify, resolve, source_file);
  } else {
    log_debug(class, resolve)("%s %s (verification)", verify, resolve);
  }
}

// Prints the end-verification message to the appropriate output.
void Verifier::log_end_verification(outputStream* st, const char* klassName, Symbol* exception_name, oop pending_exception) {
  if (pending_exception != NULL) {
    st->print("Verification for %s has", klassName);
    oop message = java_lang_Throwable::message(pending_exception);
    if (message != NULL) {
      char* ex_msg = java_lang_String::as_utf8_string(message);
      st->print_cr(" exception pending '%s %s'",
                   pending_exception->klass()->external_name(), ex_msg);
    } else {
      st->print_cr(" exception pending %s ",
                   pending_exception->klass()->external_name());
    }
  } else if (exception_name != NULL) {
    st->print_cr("Verification for %s failed", klassName);
  }
  st->print_cr("End class verification for: %s", klassName);
}

bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) {
  HandleMark hm(THREAD);
  ResourceMark rm(THREAD);

  // Eagerly allocate the identity hash code for a klass. This is a fallout
  // from 6320749 and 8059924: hash code generator is not supposed to be called
  // during the safepoint, but it allows to sneak the hashcode in during
  // verification. Without this eager hashcode generation, we may end up
  // installing the hashcode during some other operation, which may be at
  // safepoint -- blowing up the checks. It was previously done as the side
  // effect (sic!) for external_name(), but instead of doing that, we opt to
  // explicitly push the hashcode in here. This is signify the following block
  // is IMPORTANT:
  if (klass->java_mirror() != NULL) {
    klass->java_mirror()->identity_hash();
  }

  if (!is_eligible_for_verification(klass, should_verify_class)) {
    return true;
  }

  // Timer includes any side effects of class verification (resolution,
  // etc), but not recursive calls to Verifier::verify().
  JavaThread* jt = THREAD;
  PerfClassTraceTime timer(ClassLoader::perf_class_verify_time(),
                           ClassLoader::perf_class_verify_selftime(),
                           ClassLoader::perf_classes_verified(),
                           jt->get_thread_stat()->perf_recursion_counts_addr(),
                           jt->get_thread_stat()->perf_timers_addr(),
                           PerfClassTraceTime::CLASS_VERIFY);

  // If the class should be verified, first see if we can use the split
  // verifier.  If not, or if verification fails and can failover, then
  // call the inference verifier.
  Symbol* exception_name = NULL;
  const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
  char* message_buffer = NULL;
  char* exception_message = NULL;

  log_info(class, init)("Start class verification for: %s", klass->external_name());
  if (klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
    ClassVerifier split_verifier(jt, klass);
    // We don't use CHECK here, or on inference_verify below, so that we can log any exception.
    split_verifier.verify_class(THREAD);
    exception_name = split_verifier.result();

    // If DumpSharedSpaces is set then don't fall back to the old verifier on
    // verification failure. If a class fails verification with the split verifier,
    // it might fail the CDS runtime verifier constraint check. In that case, we
    // don't want to share the class. We only archive classes that pass the split
    // verifier.
    bool can_failover = !DumpSharedSpaces &&
      klass->major_version() < NOFAILOVER_MAJOR_VERSION;

    if (can_failover && !HAS_PENDING_EXCEPTION &&  // Split verifier doesn't set PENDING_EXCEPTION for failure
        (exception_name == vmSymbols::java_lang_VerifyError() ||
         exception_name == vmSymbols::java_lang_ClassFormatError())) {
      log_info(verification)("Fail over class verification to old verifier for: %s", klass->external_name());
      log_info(class, init)("Fail over class verification to old verifier for: %s", klass->external_name());
      message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
      exception_message = message_buffer;
      exception_name = inference_verify(
        klass, message_buffer, message_buffer_len, THREAD);
    }
    if (exception_name != NULL) {
      exception_message = split_verifier.exception_message();
    }
  } else {
    message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
    exception_message = message_buffer;
    exception_name = inference_verify(
        klass, message_buffer, message_buffer_len, THREAD);
  }

  LogTarget(Info, class, init) lt1;
  if (lt1.is_enabled()) {
    LogStream ls(lt1);
    log_end_verification(&ls, klass->external_name(), exception_name, PENDING_EXCEPTION);
  }
  LogTarget(Info, verification) lt2;
  if (lt2.is_enabled()) {
    LogStream ls(lt2);
    log_end_verification(&ls, klass->external_name(), exception_name, PENDING_EXCEPTION);
  }

  if (HAS_PENDING_EXCEPTION) {
    return false// use the existing exception
  } else if (exception_name == NULL) {
    return true// verification succeeded
  } else { // VerifyError or ClassFormatError to be created and thrown
    Klass* kls =
      SystemDictionary::resolve_or_fail(exception_name, true, CHECK_false);
    if (log_is_enabled(Debug, class, resolve)) {
      Verifier::trace_class_resolution(kls, klass);
    }

    while (kls != NULL) {
      if (kls == klass) {
        // If the class being verified is the exception we're creating
        // or one of it's superclasses, we're in trouble and are going
        // to infinitely recurse when we try to initialize the exception.
        // So bail out here by throwing the preallocated VM error.
        THROW_OOP_(Universe::virtual_machine_error_instance(), false);
      }
      kls = kls->super();
    }
    if (message_buffer != NULL) {
      message_buffer[message_buffer_len - 1] = '\0'// just to be sure
    }
    assert(exception_message != NULL, "");
    THROW_MSG_(exception_name, exception_message, false);
  }
}

bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class) {
  Symbol* name = klass->name();
  Klass* refl_magic_klass = vmClasses::reflect_MagicAccessorImpl_klass();

  bool is_reflect = refl_magic_klass != NULL && klass->is_subtype_of(refl_magic_klass);

  return (should_verify_for(klass->class_loader(), should_verify_class) &&
    // return if the class is a bootstrapping class
    // or defineClass specified not to verify by default (flags override passed arg)
    // We need to skip the following four for bootstraping
    name != vmSymbols::java_lang_Object() &&
    name != vmSymbols::java_lang_Class() &&
    name != vmSymbols::java_lang_String() &&
    name != vmSymbols::java_lang_Throwable() &&

    // Can not verify the bytecodes for shared classes because they have
    // already been rewritten to contain constant pool cache indices,
    // which the verifier can't understand.
    // Shared classes shouldn't have stackmaps either.
    // However, bytecodes for shared old classes can be verified because
    // they have not been rewritten.
    !(klass->is_shared() && klass->is_rewritten()) &&

    // As of the fix for 4486457 we disable verification for all of the
    // dynamically-generated bytecodes associated with the 1.4
    // reflection implementation, not just those associated with
    // jdk/internal/reflect/SerializationConstructorAccessor.
    // NOTE: this is called too early in the bootstrapping process to be
    // guarded by Universe::is_gte_jdk14x_version().
    // Also for lambda generated code, gte jdk8
    (!is_reflect));
}

Symbol* Verifier::inference_verify(
    InstanceKlass* klass, char* message, size_t message_len, TRAPS) {
  JavaThread* thread = THREAD;

  verify_byte_codes_fn_t verify_func = verify_byte_codes_fn();

  if (verify_func == NULL) {
    jio_snprintf(message, message_len, "Could not link verifier");
    return vmSymbols::java_lang_VerifyError();
  }

  ResourceMark rm(thread);
  log_info(verification)("Verifying class %s with old format", klass->external_name());

  jclass cls = (jclass) JNIHandles::make_local(thread, klass->java_mirror());
  jint result;

  {
    HandleMark hm(thread);
    ThreadToNativeFromVM ttn(thread);
    // ThreadToNativeFromVM takes care of changing thread_state, so safepoint
    // code knows that we have left the VM
    JNIEnv *env = thread->jni_environment();
    result = (*verify_func)(env, cls, message, (int)message_len, klass->major_version());
  }

  JNIHandles::destroy_local(cls);

  // These numbers are chosen so that VerifyClassCodes interface doesn't need
  // to be changed (still return jboolean (unsigned char)), and result is
  // 1 when verification is passed.
  if (result == 0) {
    return vmSymbols::java_lang_VerifyError();
  } else if (result == 1) {
    return NULL; // verified.
  } else if (result == 2) {
    THROW_MSG_(vmSymbols::java_lang_OutOfMemoryError(), message, NULL);
  } else if (result == 3) {
    return vmSymbols::java_lang_ClassFormatError();
  } else {
    ShouldNotReachHere();
    return NULL;
  }
}

TypeOrigin TypeOrigin::null() {
  return TypeOrigin();
}
TypeOrigin TypeOrigin::local(u2 index, StackMapFrame* frame) {
  assert(frame != NULL, "Must have a frame");
  return TypeOrigin(CF_LOCALS, index, StackMapFrame::copy(frame),
     frame->local_at(index));
}
TypeOrigin TypeOrigin::stack(u2 index, StackMapFrame* frame) {
  assert(frame != NULL, "Must have a frame");
  return TypeOrigin(CF_STACK, index, StackMapFrame::copy(frame),
      frame->stack_at(index));
}
TypeOrigin TypeOrigin::sm_local(u2 index, StackMapFrame* frame) {
  assert(frame != NULL, "Must have a frame");
  return TypeOrigin(SM_LOCALS, index, StackMapFrame::copy(frame),
      frame->local_at(index));
}
TypeOrigin TypeOrigin::sm_stack(u2 index, StackMapFrame* frame) {
  assert(frame != NULL, "Must have a frame");
  return TypeOrigin(SM_STACK, index, StackMapFrame::copy(frame),
      frame->stack_at(index));
}
TypeOrigin TypeOrigin::bad_index(u2 index) {
  return TypeOrigin(BAD_INDEX, index, NULL, VerificationType::bogus_type());
}
TypeOrigin TypeOrigin::cp(u2 index, VerificationType vt) {
  return TypeOrigin(CONST_POOL, index, NULL, vt);
}
TypeOrigin TypeOrigin::signature(VerificationType vt) {
  return TypeOrigin(SIG, 0, NULL, vt);
}
TypeOrigin TypeOrigin::implicit(VerificationType t) {
  return TypeOrigin(IMPLICIT, 0, NULL, t);
}
TypeOrigin TypeOrigin::frame(StackMapFrame* frame) {
  return TypeOrigin(FRAME_ONLY, 0, StackMapFrame::copy(frame),
                    VerificationType::bogus_type());
}

void TypeOrigin::reset_frame() {
  if (_frame != NULL) {
    _frame->restore();
  }
}

void TypeOrigin::details(outputStream* ss) const {
  _type.print_on(ss);
  switch (_origin) {
    case CF_LOCALS:
      ss->print(" (current frame, locals[%d])", _index);
      break;
    case CF_STACK:
      ss->print(" (current frame, stack[%d])", _index);
      break;
    case SM_LOCALS:
      ss->print(" (stack map, locals[%d])", _index);
      break;
    case SM_STACK:
      ss->print(" (stack map, stack[%d])", _index);
      break;
    case CONST_POOL:
      ss->print(" (constant pool %d)", _index);
      break;
    case SIG:
      ss->print(" (from method signature)");
      break;
    case IMPLICIT:
    case FRAME_ONLY:
    case NONE:
    default:
      ;
  }
}

#ifdef ASSERT
void TypeOrigin::print_on(outputStream* str) const {
  str->print("{%d,%d,%p:", _origin, _index, _frame);
  if (_frame != NULL) {
    _frame->print_on(str);
  } else {
    str->print("null");
  }
  str->print(",");
  _type.print_on(str);
  str->print("}");
}
#endif

void ErrorContext::details(outputStream* ss, const Method* method) const {
  if (is_valid()) {
    ss->cr();
    ss->print_cr("Exception Details:");
    location_details(ss, method);
    reason_details(ss);
    frame_details(ss);
    bytecode_details(ss, method);
    handler_details(ss, method);
    stackmap_details(ss, method);
  }
}

void ErrorContext::reason_details(outputStream* ss) const {
  streamIndentor si(ss);
  ss->indent().print_cr("Reason:");
  streamIndentor si2(ss);
  ss->indent().print("%s""");
  switch (_fault) {
    case INVALID_BYTECODE:
      ss->print("Error exists in the bytecode");
      break;
    case WRONG_TYPE:
      if (_expected.is_valid()) {
        ss->print("Type ");
        _type.details(ss);
        ss->print(" is not assignable to ");
        _expected.details(ss);
      } else {
        ss->print("Invalid type: ");
        _type.details(ss);
      }
      break;
    case FLAGS_MISMATCH:
      if (_expected.is_valid()) {
        ss->print("Current frame's flags are not assignable "
                  "to stack map frame's.");
      } else {
        ss->print("Current frame's flags are invalid in this context.");
      }
      break;
    case BAD_CP_INDEX:
      ss->print("Constant pool index %d is invalid", _type.index());
      break;
    case BAD_LOCAL_INDEX:
      ss->print("Local index %d is invalid", _type.index());
      break;
    case LOCALS_SIZE_MISMATCH:
      ss->print("Current frame's local size doesn't match stackmap.");
      break;
    case STACK_SIZE_MISMATCH:
      ss->print("Current frame's stack size doesn't match stackmap.");
      break;
    case STACK_OVERFLOW:
      ss->print("Exceeded max stack size.");
      break;
    case STACK_UNDERFLOW:
      ss->print("Attempt to pop empty stack.");
      break;
    case MISSING_STACKMAP:
      ss->print("Expected stackmap frame at this location.");
      break;
    case BAD_STACKMAP:
      ss->print("Invalid stackmap specification.");
      break;
    case UNKNOWN:
    default:
      ShouldNotReachHere();
      ss->print_cr("Unknown");
  }
  ss->cr();
}

void ErrorContext::location_details(outputStream* ss, const Method* method) const {
  if (_bci != -1 && method != NULL) {
    streamIndentor si(ss);
    const char* bytecode_name = "";
    if (method->validate_bci(_bci) != -1) {
      Bytecodes::Code code = Bytecodes::code_or_bp_at(method->bcp_from(_bci));
      if (Bytecodes::is_defined(code)) {
          bytecode_name = Bytecodes::name(code);
      } else {
          bytecode_name = "";
      }
    }
    InstanceKlass* ik = method->method_holder();
    ss->indent().print_cr("Location:");
    streamIndentor si2(ss);
    ss->indent().print_cr("%s.%s%s @%d: %s",
        ik->name()->as_C_string(), method->name()->as_C_string(),
        method->signature()->as_C_string(), _bci, bytecode_name);
  }
}

void ErrorContext::frame_details(outputStream* ss) const {
  streamIndentor si(ss);
  if (_type.is_valid() && _type.frame() != NULL) {
    ss->indent().print_cr("Current Frame:");
    streamIndentor si2(ss);
    _type.frame()->print_on(ss);
  }
  if (_expected.is_valid() && _expected.frame() != NULL) {
    ss->indent().print_cr("Stackmap Frame:");
    streamIndentor si2(ss);
    _expected.frame()->print_on(ss);
  }
}

void ErrorContext::bytecode_details(outputStream* ss, const Method* method) const {
  if (method != NULL) {
    streamIndentor si(ss);
    ss->indent().print_cr("Bytecode:");
    streamIndentor si2(ss);
    ss->print_data(method->code_base(), method->code_size(), false);
  }
}

void ErrorContext::handler_details(outputStream* ss, const Method* method) const {
  if (method != NULL) {
    streamIndentor si(ss);
    ExceptionTable table(method);
    if (table.length() > 0) {
      ss->indent().print_cr("Exception Handler Table:");
      streamIndentor si2(ss);
      for (int i = 0; i < table.length(); ++i) {
        ss->indent().print_cr("bci [%d, %d] => handler: %d", table.start_pc(i),
            table.end_pc(i), table.handler_pc(i));
      }
    }
  }
}

void ErrorContext::stackmap_details(outputStream* ss, const Method* method) const {
  if (method != NULL && method->has_stackmap_table()) {
    streamIndentor si(ss);
    ss->indent().print_cr("Stackmap Table:");
    Array<u1>* data = method->stackmap_data();
    stack_map_table* sm_table =
        stack_map_table::at((address)data->adr_at(0));
    stack_map_frame* sm_frame = sm_table->entries();
    streamIndentor si2(ss);
    int current_offset = -1;
    address end_of_sm_table = (address)sm_table + method->stackmap_data()->length();
    for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
      ss->indent();
      if (!sm_frame->verify((address)sm_frame, end_of_sm_table)) {
        sm_frame->print_truncated(ss, current_offset);
        return;
      }
      sm_frame->print_on(ss, current_offset);
      ss->cr();
      current_offset += sm_frame->offset_delta();
      sm_frame = sm_frame->next();
    }
  }
}

// Methods in ClassVerifier

ClassVerifier::ClassVerifier(JavaThread* current, InstanceKlass* klass)
    : _thread(current), _previous_symbol(NULL), _symbols(NULL), _exception_type(NULL),
      _message(NULL), _klass(klass) {
  _this_type = VerificationType::reference_type(klass->name());
}

ClassVerifier::~ClassVerifier() {
  // Decrement the reference count for any symbols created.
  if (_symbols != NULL) {
    for (int i = 0; i < _symbols->length(); i++) {
      Symbol* s = _symbols->at(i);
      s->decrement_refcount();
    }
  }
}

VerificationType ClassVerifier::object_type() const {
  return VerificationType::reference_type(vmSymbols::java_lang_Object());
}

TypeOrigin ClassVerifier::ref_ctx(const char* sig) {
  VerificationType vt = VerificationType::reference_type(
                         create_temporary_symbol(sig, (int)strlen(sig)));
  return TypeOrigin::implicit(vt);
}


void ClassVerifier::verify_class(TRAPS) {
  log_info(verification)("Verifying class %s with new format", _klass->external_name());

  // Either verifying both local and remote classes or just remote classes.
  assert(BytecodeVerificationRemote, "Should not be here");

  Array<Method*>* methods = _klass->methods();
  int num_methods = methods->length();

  for (int index = 0; index < num_methods; index++) {
    // Check for recursive re-verification before each method.
    if (was_recursively_verified()) return;

    Method* m = methods->at(index);
    if (m->is_native() || m->is_abstract() || m->is_overpass()) {
      // If m is native or abstract, skip it.  It is checked in class file
      // parser that methods do not override a final method.  Overpass methods
      // are trusted since the VM generates them.
      continue;
    }
    verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
  }

  if (was_recursively_verified()){
    log_info(verification)("Recursive verification detected for: %s", _klass->external_name());
    log_info(class, init)("Recursive verification detected for: %s",
                        _klass->external_name());
  }
}

// Translate the signature entries into verification types and save them in
// the growable array.  Also, save the count of arguments.
void ClassVerifier::translate_signature(Symbol* const method_sig,
                                        sig_as_verification_types* sig_verif_types) {
  SignatureStream sig_stream(method_sig);
  VerificationType sig_type[2];
  int sig_i = 0;
  GrowableArray<VerificationType>* verif_types = sig_verif_types->sig_verif_types();

  // Translate the signature arguments into verification types.
  while (!sig_stream.at_return_type()) {
    int n = change_sig_to_verificationType(&sig_stream, sig_type);
    assert(n <= 2, "Unexpected signature type");

    // Store verification type(s).  Longs and Doubles each have two verificationTypes.
    for (int x = 0; x < n; x++) {
      verif_types->push(sig_type[x]);
    }
    sig_i += n;
    sig_stream.next();
  }

  // Set final arg count, not including the return type.  The final arg count will
  // be compared with sig_verify_types' length to see if there is a return type.
  sig_verif_types->set_num_args(sig_i);

  // Store verification type(s) for the return type, if there is one.
  if (sig_stream.type() != T_VOID) {
    int n = change_sig_to_verificationType(&sig_stream, sig_type);
    assert(n <= 2, "Unexpected signature return type");
    for (int y = 0; y < n; y++) {
      verif_types->push(sig_type[y]);
    }
  }
}

void ClassVerifier::create_method_sig_entry(sig_as_verification_types* sig_verif_types,
                                            int sig_index) {
  // Translate the signature into verification types.
  ConstantPool* cp = _klass->constants();
  Symbol* const method_sig = cp->symbol_at(sig_index);
  translate_signature(method_sig, sig_verif_types);

  // Add the list of this signature's verification types to the table.
  bool is_unique = method_signatures_table()->put(sig_index, sig_verif_types);
  assert(is_unique, "Duplicate entries in method_signature_table");
}

void ClassVerifier::verify_method(const methodHandle& m, TRAPS) {
  HandleMark hm(THREAD);
  _method = m;   // initialize _method
  log_info(verification)("Verifying method %s", m->name_and_sig_as_C_string());

// For clang, the only good constant format string is a literal constant format string.
#define bad_type_msg "Bad type on operand stack in %s"

  int32_t max_stack = m->verifier_max_stack();
  int32_t max_locals = m->max_locals();
  constantPoolHandle cp(THREAD, m->constants());

  // Method signature was checked in ClassFileParser.
  assert(SignatureVerifier::is_valid_method_signature(m->signature()),
         "Invalid method signature");

  // Initial stack map frame: offset is 0, stack is initially empty.
  StackMapFrame current_frame(max_locals, max_stack, this);
  // Set initial locals
  VerificationType return_type = current_frame.set_locals_from_arg( m, current_type());

  int32_t stackmap_index = 0; // index to the stackmap array

  u4 code_length = m->code_size();

  // Scan the bytecode and map each instruction's start offset to a number.
  char* code_data = generate_code_data(m, code_length, CHECK_VERIFY(this));

  int ex_min = code_length;
  int ex_max = -1;
  // Look through each item on the exception table. Each of the fields must refer
  // to a legal instruction.
  if (was_recursively_verified()) return;
  verify_exception_handler_table(
    code_length, code_data, ex_min, ex_max, CHECK_VERIFY(this));

  // Look through each entry on the local variable table and make sure
  // its range of code array offsets is valid. (4169817)
  if (m->has_localvariable_table()) {
    verify_local_variable_table(code_length, code_data, CHECK_VERIFY(this));
  }

  Array<u1>* stackmap_data = m->stackmap_data();
  StackMapStream stream(stackmap_data);
  StackMapReader reader(this, &stream, code_data, code_length, THREAD);
  StackMapTable stackmap_table(&reader, ¤t_frame, max_locals, max_stack,
                               code_data, code_length, CHECK_VERIFY(this));

  LogTarget(Debug, verification) lt;
  if (lt.is_enabled()) {
    ResourceMark rm(THREAD);
    LogStream ls(lt);
    stackmap_table.print_on(&ls);
  }

  RawBytecodeStream bcs(m);

  // Scan the byte code linearly from the start to the end
  bool no_control_flow = false// Set to true when there is no direct control
                                // flow from current instruction to the next
                                // instruction in sequence

  Bytecodes::Code opcode;
  while (!bcs.is_last_bytecode()) {
    // Check for recursive re-verification before each bytecode.
    if (was_recursively_verified())  return;

    opcode = bcs.raw_next();
    u2 bci = bcs.bci();

    // Set current frame's offset to bci
    current_frame.set_offset(bci);
    current_frame.set_mark();

    // Make sure every offset in stackmap table point to the beginning to
    // an instruction. Match current_frame to stackmap_table entry with
    // the same offset if exists.
    stackmap_index = verify_stackmap_table(
      stackmap_index, bci, ¤t_frame, &stackmap_table,
      no_control_flow, CHECK_VERIFY(this));


    bool this_uninit = false;  // Set to true when invokespecial <init> initialized 'this'
    bool verified_exc_handlers = false;

    // Merge with the next instruction
    {
      u2 index;
      int target;
      VerificationType type, type2;
      VerificationType atype;

      LogTarget(Debug, verification) lt;
      if (lt.is_enabled()) {
        ResourceMark rm(THREAD);
        LogStream ls(lt);
        current_frame.print_on(&ls);
        lt.print("offset = %d, opcode = %s", bci,
                 opcode == Bytecodes::_illegal ? "illegal" : Bytecodes::name(opcode));
      }

      // Make sure wide instruction is in correct format
      if (bcs.is_wide()) {
        if (opcode != Bytecodes::_iinc   && opcode != Bytecodes::_iload  &&
            opcode != Bytecodes::_aload  && opcode != Bytecodes::_lload  &&
            opcode != Bytecodes::_istore && opcode != Bytecodes::_astore &&
            opcode != Bytecodes::_lstore && opcode != Bytecodes::_fload  &&
            opcode != Bytecodes::_dload  && opcode != Bytecodes::_fstore &&
            opcode != Bytecodes::_dstore) {
          /* Unreachable?  RawBytecodeStream's raw_next() returns 'illegal'
           * if we encounter a wide instruction that modifies an invalid
           * opcode (not one of the ones listed above) */

          verify_error(ErrorContext::bad_code(bci), "Bad wide instruction");
          return;
        }
      }

      // Look for possible jump target in exception handlers and see if it
      // matches current_frame.  Do this check here for astore*, dstore*,
      // fstore*, istore*, and lstore* opcodes because they can change the type
      // state by adding a local.  JVM Spec says that the incoming type state
      // should be used for this check.  So, do the check here before a possible
      // local is added to the type state.
      if (Bytecodes::is_store_into_local(opcode) && bci >= ex_min && bci < ex_max) {
        if (was_recursively_verified()) return;
        verify_exception_handler_targets(
          bci, this_uninit, ¤t_frame, &stackmap_table, CHECK_VERIFY(this));
        verified_exc_handlers = true;
      }

      if (was_recursively_verified()) return;

      switch (opcode) {
        case Bytecodes::_nop :
          no_control_flow = falsebreak;
        case Bytecodes::_aconst_null :
          current_frame.push_stack(
            VerificationType::null_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iconst_m1 :
        case Bytecodes::_iconst_0 :
        case Bytecodes::_iconst_1 :
        case Bytecodes::_iconst_2 :
        case Bytecodes::_iconst_3 :
        case Bytecodes::_iconst_4 :
        case Bytecodes::_iconst_5 :
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lconst_0 :
        case Bytecodes::_lconst_1 :
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fconst_0 :
        case Bytecodes::_fconst_1 :
        case Bytecodes::_fconst_2 :
          current_frame.push_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dconst_0 :
        case Bytecodes::_dconst_1 :
          current_frame.push_stack_2(
            VerificationType::double_type(),
            VerificationType::double2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_sipush :
        case Bytecodes::_bipush :
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_ldc :
          verify_ldc(
            opcode, bcs.get_index_u1(), ¤t_frame,
            cp, bci, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_ldc_w :
        case Bytecodes::_ldc2_w :
          verify_ldc(
            opcode, bcs.get_index_u2(), ¤t_frame,
            cp, bci, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iload :
          verify_iload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iload_0 :
        case Bytecodes::_iload_1 :
        case Bytecodes::_iload_2 :
        case Bytecodes::_iload_3 :
          index = opcode - Bytecodes::_iload_0;
          verify_iload(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lload :
          verify_lload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lload_0 :
        case Bytecodes::_lload_1 :
        case Bytecodes::_lload_2 :
        case Bytecodes::_lload_3 :
          index = opcode - Bytecodes::_lload_0;
          verify_lload(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fload :
          verify_fload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fload_0 :
        case Bytecodes::_fload_1 :
        case Bytecodes::_fload_2 :
        case Bytecodes::_fload_3 :
          index = opcode - Bytecodes::_fload_0;
          verify_fload(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dload :
          verify_dload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dload_0 :
        case Bytecodes::_dload_1 :
        case Bytecodes::_dload_2 :
        case Bytecodes::_dload_3 :
          index = opcode - Bytecodes::_dload_0;
          verify_dload(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_aload :
          verify_aload(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_aload_0 :
        case Bytecodes::_aload_1 :
        case Bytecodes::_aload_2 :
        case Bytecodes::_aload_3 :
          index = opcode - Bytecodes::_aload_0;
          verify_aload(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iaload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_int_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[I")),
                bad_type_msg, "iaload");
            return;
          }
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_baload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_bool_array() && !atype.is_byte_array()) {
            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "baload");
            return;
          }
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_caload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_char_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[C")),
                bad_type_msg, "caload");
            return;
          }
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_saload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_short_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[S")),
                bad_type_msg, "saload");
            return;
          }
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_laload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_long_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[J")),
                bad_type_msg, "laload");
            return;
          }
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_faload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_float_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[F")),
                bad_type_msg, "faload");
            return;
          }
          current_frame.push_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_daload :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_double_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[D")),
                bad_type_msg, "daload");
            return;
          }
          current_frame.push_stack_2(
            VerificationType::double_type(),
            VerificationType::double2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_aaload : {
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_reference_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(),
                TypeOrigin::implicit(VerificationType::reference_check())),
                bad_type_msg, "aaload");
            return;
          }
          if (atype.is_null()) {
            current_frame.push_stack(
              VerificationType::null_type(), CHECK_VERIFY(this));
          } else {
            VerificationType component = atype.get_component(this);
            current_frame.push_stack(component, CHECK_VERIFY(this));
          }
          no_control_flow = falsebreak;
        }
        case Bytecodes::_istore :
          verify_istore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_istore_0 :
        case Bytecodes::_istore_1 :
        case Bytecodes::_istore_2 :
        case Bytecodes::_istore_3 :
          index = opcode - Bytecodes::_istore_0;
          verify_istore(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lstore :
          verify_lstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lstore_0 :
        case Bytecodes::_lstore_1 :
        case Bytecodes::_lstore_2 :
        case Bytecodes::_lstore_3 :
          index = opcode - Bytecodes::_lstore_0;
          verify_lstore(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fstore :
          verify_fstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fstore_0 :
        case Bytecodes::_fstore_1 :
        case Bytecodes::_fstore_2 :
        case Bytecodes::_fstore_3 :
          index = opcode - Bytecodes::_fstore_0;
          verify_fstore(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dstore :
          verify_dstore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dstore_0 :
        case Bytecodes::_dstore_1 :
        case Bytecodes::_dstore_2 :
        case Bytecodes::_dstore_3 :
          index = opcode - Bytecodes::_dstore_0;
          verify_dstore(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_astore :
          verify_astore(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_astore_0 :
        case Bytecodes::_astore_1 :
        case Bytecodes::_astore_2 :
        case Bytecodes::_astore_3 :
          index = opcode - Bytecodes::_astore_0;
          verify_astore(index, ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iastore :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          type2 = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_int_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[I")),
                bad_type_msg, "iastore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_bastore :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          type2 = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_bool_array() && !atype.is_byte_array()) {
            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "bastore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_castore :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_char_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[C")),
                bad_type_msg, "castore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_sastore :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_short_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[S")),
                bad_type_msg, "sastore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_lastore :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_long_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[J")),
                bad_type_msg, "lastore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_fastore :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.pop_stack
            (VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_float_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[F")),
                bad_type_msg, "fastore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_dastore :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          if (!atype.is_double_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(), ref_ctx("[D")),
                bad_type_msg, "dastore");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_aastore :
          type = current_frame.pop_stack(object_type(), CHECK_VERIFY(this));
          type2 = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          atype = current_frame.pop_stack(
            VerificationType::reference_check(), CHECK_VERIFY(this));
          // more type-checking is done at runtime
          if (!atype.is_reference_array()) {
            verify_error(ErrorContext::bad_type(bci,
                current_frame.stack_top_ctx(),
                TypeOrigin::implicit(VerificationType::reference_check())),
                bad_type_msg, "aastore");
            return;
          }
          // 4938384: relaxed constraint in JVMS 3rd edition.
          no_control_flow = falsebreak;
        case Bytecodes::_pop :
          current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_pop2 :
          type = current_frame.pop_stack(CHECK_VERIFY(this));
          if (type.is_category1()) {
            current_frame.pop_stack(
              VerificationType::category1_check(), CHECK_VERIFY(this));
          } else if (type.is_category2_2nd()) {
            current_frame.pop_stack(
              VerificationType::category2_check(), CHECK_VERIFY(this));
          } else {
            /* Unreachable? Would need a category2_1st on TOS
             * which does not appear possible. */

            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "pop2");
            return;
          }
          no_control_flow = falsebreak;
        case Bytecodes::_dup :
          type = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dup_x1 :
          type = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          type2 = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dup_x2 :
        {
          VerificationType type3;
          type = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          type2 = current_frame.pop_stack(CHECK_VERIFY(this));
          if (type2.is_category1()) {
            type3 = current_frame.pop_stack(
              VerificationType::category1_check(), CHECK_VERIFY(this));
          } else if (type2.is_category2_2nd()) {
            type3 = current_frame.pop_stack(
              VerificationType::category2_check(), CHECK_VERIFY(this));
          } else {
            /* Unreachable? Would need a category2_1st at stack depth 2 with
             * a category1 on TOS which does not appear possible. */

            verify_error(ErrorContext::bad_type(
                bci, current_frame.stack_top_ctx()), bad_type_msg, "dup_x2");
            return;
          }
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type3, CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        }
        case Bytecodes::_dup2 :
          type = current_frame.pop_stack(CHECK_VERIFY(this));
          if (type.is_category1()) {
            type2 = current_frame.pop_stack(
              VerificationType::category1_check(), CHECK_VERIFY(this));
          } else if (type.is_category2_2nd()) {
            type2 = current_frame.pop_stack(
              VerificationType::category2_check(), CHECK_VERIFY(this));
          } else {
            /* Unreachable?  Would need a category2_1st on TOS which does not
             * appear possible. */

            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "dup2");
            return;
          }
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dup2_x1 :
        {
          VerificationType type3;
          type = current_frame.pop_stack(CHECK_VERIFY(this));
          if (type.is_category1()) {
            type2 = current_frame.pop_stack(
              VerificationType::category1_check(), CHECK_VERIFY(this));
          } else if (type.is_category2_2nd()) {
            type2 = current_frame.pop_stack(
              VerificationType::category2_check(), CHECK_VERIFY(this));
          } else {
            /* Unreachable?  Would need a category2_1st on TOS which does
             * not appear possible. */

            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "dup2_x1");
            return;
          }
          type3 = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type3, CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        }
        case Bytecodes::_dup2_x2 :
        {
          VerificationType type3, type4;
          type = current_frame.pop_stack(CHECK_VERIFY(this));
          if (type.is_category1()) {
            type2 = current_frame.pop_stack(
              VerificationType::category1_check(), CHECK_VERIFY(this));
          } else if (type.is_category2_2nd()) {
            type2 = current_frame.pop_stack(
              VerificationType::category2_check(), CHECK_VERIFY(this));
          } else {
            /* Unreachable?  Would need a category2_1st on TOS which does
             * not appear possible. */

            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "dup2_x2");
            return;
          }
          type3 = current_frame.pop_stack(CHECK_VERIFY(this));
          if (type3.is_category1()) {
            type4 = current_frame.pop_stack(
              VerificationType::category1_check(), CHECK_VERIFY(this));
          } else if (type3.is_category2_2nd()) {
            type4 = current_frame.pop_stack(
              VerificationType::category2_check(), CHECK_VERIFY(this));
          } else {
            /* Unreachable?  Would need a category2_1st on TOS after popping
             * a long/double or two category 1's, which does not
             * appear possible. */

            verify_error(
                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
                bad_type_msg, "dup2_x2");
            return;
          }
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type4, CHECK_VERIFY(this));
          current_frame.push_stack(type3, CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        }
        case Bytecodes::_swap :
          type = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          type2 = current_frame.pop_stack(
            VerificationType::category1_check(), CHECK_VERIFY(this));
          current_frame.push_stack(type, CHECK_VERIFY(this));
          current_frame.push_stack(type2, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iadd :
        case Bytecodes::_isub :
        case Bytecodes::_imul :
        case Bytecodes::_idiv :
        case Bytecodes::_irem :
        case Bytecodes::_ishl :
        case Bytecodes::_ishr :
        case Bytecodes::_iushr :
        case Bytecodes::_ior :
        case Bytecodes::_ixor :
        case Bytecodes::_iand :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          // fall through
        case Bytecodes::_ineg :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_ladd :
        case Bytecodes::_lsub :
        case Bytecodes::_lmul :
        case Bytecodes::_ldiv :
        case Bytecodes::_lrem :
        case Bytecodes::_land :
        case Bytecodes::_lor :
        case Bytecodes::_lxor :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          // fall through
        case Bytecodes::_lneg :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lshl :
        case Bytecodes::_lshr :
        case Bytecodes::_lushr :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fadd :
        case Bytecodes::_fsub :
        case Bytecodes::_fmul :
        case Bytecodes::_fdiv :
        case Bytecodes::_frem :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          // fall through
        case Bytecodes::_fneg :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dadd :
        case Bytecodes::_dsub :
        case Bytecodes::_dmul :
        case Bytecodes::_ddiv :
        case Bytecodes::_drem :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          // fall through
        case Bytecodes::_dneg :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::double_type(),
            VerificationType::double2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_iinc :
          verify_iinc(bcs.get_index(), ¤t_frame, CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_i2l :
          type = current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
       case Bytecodes::_l2i :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_i2f :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_i2d :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::double_type(),
            VerificationType::double2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_l2f :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_l2d :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::double_type(),
            VerificationType::double2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_f2i :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_f2l :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_f2d :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::double_type(),
            VerificationType::double2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_d2i :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_d2l :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.push_stack_2(
            VerificationType::long_type(),
            VerificationType::long2_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_d2f :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_i2b :
        case Bytecodes::_i2c :
        case Bytecodes::_i2s :
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_lcmp :
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.pop_stack_2(
            VerificationType::long2_type(),
            VerificationType::long_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_fcmpl :
        case Bytecodes::_fcmpg :
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.pop_stack(
            VerificationType::float_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_dcmpl :
        case Bytecodes::_dcmpg :
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.pop_stack_2(
            VerificationType::double2_type(),
            VerificationType::double_type(), CHECK_VERIFY(this));
          current_frame.push_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          no_control_flow = falsebreak;
        case Bytecodes::_if_icmpeq:
        case Bytecodes::_if_icmpne:
        case Bytecodes::_if_icmplt:
        case Bytecodes::_if_icmpge:
        case Bytecodes::_if_icmpgt:
        case Bytecodes::_if_icmple:
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          // fall through
        case Bytecodes::_ifeq:
        case Bytecodes::_ifne:
        case Bytecodes::_iflt:
        case Bytecodes::_ifge:
        case Bytecodes::_ifgt:
        case Bytecodes::_ifle:
          current_frame.pop_stack(
            VerificationType::integer_type(), CHECK_VERIFY(this));
          target = bcs.dest();
--> --------------------

--> maximum size reached

--> --------------------

¤ Dauer der Verarbeitung: 0.82 Sekunden  (vorverarbeitet)  ¤





zum Wurzelverzeichnis wechseln
Diese Quellcodebibliothek enthält Beispiele in vielen Programmiersprachen. Man kann per Verzeichnistruktur darin navigieren. Der Code wird farblich markiert angezeigt.
zum Wurzelverzeichnis wechseln
sprechenden Kalenders

Eigene Datei ansehen




Laden

Fehler beim Verzeichnis:


in der Quellcodebibliothek suchen

Die farbliche Syntaxdarstellung ist noch experimentell.


Bot Zugriff