/*
 * Copyright (c) 1999, 2025, 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 "ci/ciConstant.hpp"
#include "ci/ciField.hpp"
#include "ci/ciKlass.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciStreams.hpp"
#include "ci/ciSymbols.hpp"
#include "ci/ciUtilities.inline.hpp"
#include "runtime/handles.inline.hpp"

// ciExceptionHandlerStream
//
// Walk over some selected set of a methods exception handlers.

// ------------------------------------------------------------------
// ciExceptionHandlerStream::count
//
// How many exception handlers are there in this stream?
//
// Implementation note: Compiler2 needs this functionality, so I had
int ciExceptionHandlerStream::count() {
  int save_pos = _pos;
  int save_end = _end;

  int count = 0;

  _pos = -1;
  _end = _method->_handler_count;


  next();
  while (!is_done()) {
    count++;
    next();
  }

  _pos = save_pos;
  _end = save_end;

  return count;
}

int ciExceptionHandlerStream::count_remaining() {
  int save_pos = _pos;
  int save_end = _end;

  int count = 0;

  while (!is_done()) {
    count++;
    next();
  }

  _pos = save_pos;
  _end = save_end;

  return count;
}

// ciBytecodeStream
//
// The class is used to iterate over the bytecodes of a method.
// It hides the details of constant pool structure/access by
// providing accessors for constant pool items.

// ------------------------------------------------------------------
// ciBytecodeStream::next_wide_or_table
//
// Special handling for switch ops
Bytecodes::Code ciBytecodeStream::next_wide_or_table(Bytecodes::Code bc) {
  switch (bc) {                // Check for special bytecode handling
  case Bytecodes::_wide:
    // Special handling for the wide bytcode
    // Get following bytecode; do not return wide
    assert(Bytecodes::Code(_pc[0]) == Bytecodes::_wide, "");
    bc = Bytecodes::java_code(_raw_bc = (Bytecodes::Code)_pc[1]);
    assert(Bytecodes::wide_length_for(bc) > 2, "must make progress");
    _pc += Bytecodes::wide_length_for(bc);
    _was_wide = _pc;              // Flag last wide bytecode found
    assert(is_wide(), "accessor works right");
    break;

  case Bytecodes::_lookupswitch:
    _pc++;                      // Skip wide bytecode
    _pc += (_start-_pc)&3;      // Word align
    _table_base = (jint*)_pc;   // Capture for later usage
                                // table_base[0] is default far_dest
    // Table has 2 lead elements (default, length), then pairs of u4 values.
    // So load table length, and compute address at end of table
    _pc = (address)&_table_base[2+ 2*Bytes::get_Java_u4((address)&_table_base[1])];
    break;

  case Bytecodes::_tableswitch: {
    _pc++;                      // Skip wide bytecode
    _pc += (_start-_pc)&3;      // Word align
    _table_base = (jint*)_pc;   // Capture for later usage
                                // table_base[0] is default far_dest
    int lo = Bytes::get_Java_u4((address)&_table_base[1]);// Low bound
    int hi = Bytes::get_Java_u4((address)&_table_base[2]);// High bound
    int len = hi - lo + 1;      // Dense table size
    _pc = (address)&_table_base[3+len]; // Skip past table
    break;
  }

  default:
    fatal("unhandled bytecode : Current Method = %s, BCI = %d, OPCODE = %s (0x%X)", _method->name()->as_utf8(), cur_bci(), Bytecodes::name(bc), bc);
  }
  return bc;
}

// ------------------------------------------------------------------
// ciBytecodeStream::reset_to_bci
void ciBytecodeStream::reset_to_bci( int bci ) {
  _bc_start = _was_wide = nullptr;
  _pc = _start+bci;
}

// ------------------------------------------------------------------
// ciBytecodeStream::force_bci
void ciBytecodeStream::force_bci(int bci) {
  if (bci < 0) {
    reset_to_bci(0);
    _bc_start = _start + bci;
    _bc = EOBC();
  } else {
    reset_to_bci(bci);
    next();
  }
}


// ------------------------------------------------------------------
// Constant pool access
// ------------------------------------------------------------------

// ------------------------------------------------------------------
// ciBytecodeStream::get_klass_index
//
// If this bytecodes references a klass, return the index of the
// referenced klass.
int ciBytecodeStream::get_klass_index() const {
  switch(cur_bc()) {
  case Bytecodes::_ldc:
    return get_index_u1();
  case Bytecodes::_ldc_w:
  case Bytecodes::_ldc2_w:
  case Bytecodes::_checkcast:
  case Bytecodes::_instanceof:
  case Bytecodes::_anewarray:
  case Bytecodes::_multianewarray:
  case Bytecodes::_new:
  case Bytecodes::_newarray:
    return get_index_u2();
  default:
    ShouldNotReachHere();
    return 0;
  }
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_klass
//
// If this bytecode is a new, newarray, multianewarray, instanceof,
// or checkcast, get the referenced klass.
ciKlass* ciBytecodeStream::get_klass(bool& will_link) {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  return CURRENT_ENV->get_klass_by_index(cpool, get_klass_index(), will_link, _holder);
}

// ciBytecodeStream::get_klass
//
// If this bytecode is a new, newarray, multianewarray, instanceof,
// or checkcast, get the referenced klass. Retuns an unloaded ciKlass
// if the referenced klass is not accessible.
ciKlass* ciBytecodeStream::get_klass() {
  bool will_link;
  ciKlass* klass = get_klass(will_link);
  if (!will_link && klass->is_loaded()) { // klass not accessible
    VM_ENTRY_MARK;
    klass = CURRENT_ENV->get_unloaded_klass(_holder, klass->name());
  }
  return klass;
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_raw_index
//
// If this bytecode is one of the ldc variants, get the index of the
// referenced constant.
int ciBytecodeStream::get_constant_raw_index() const {
  // work-alike for Bytecode_loadconstant::raw_index()
  switch (cur_bc()) {
  case Bytecodes::_ldc:
    return get_index_u1();
  case Bytecodes::_ldc_w:
  case Bytecodes::_ldc2_w:
    return get_index_u2();
  default:
    ShouldNotReachHere();
    return 0;
  }
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_pool_index
// Decode any reference index into a regular pool index.
int ciBytecodeStream::get_constant_pool_index() const {
  // work-alike for Bytecode_loadconstant::pool_index()
  int index = get_constant_raw_index();
  if (has_cache_index()) {
    VM_ENTRY_MARK;
    constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
    return cpool->object_to_cp_index(index);
  }
  return index;
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_constant
//
// If this bytecode is one of the ldc variants, get the referenced
// constant.
ciConstant ciBytecodeStream::get_constant() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  int pool_index = get_constant_raw_index();
  int cache_index = -1;
  if (has_cache_index()) {
    cache_index = pool_index;
    pool_index = cpool->object_to_cp_index(cache_index);
  } else if (cpool->tag_at(pool_index).is_dynamic_constant() ||
             cpool->tag_at(pool_index).is_dynamic_constant_in_error()) {
    // Condy with primitive type is not quickened, so the index into resolved reference cache should be reconstructed.
    assert(is_java_primitive(cpool->basic_type_for_constant_at(pool_index)), "not quickened");
    cache_index = cpool->cp_to_object_index(pool_index);
  }
  return CURRENT_ENV->get_constant_by_index(cpool, pool_index, cache_index, _holder);
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_constant_pool_tag
//
// If this bytecode is one of the ldc variants, get the referenced
// constant.
constantTag ciBytecodeStream::get_constant_pool_tag(int cp_index) const {
  VM_ENTRY_MARK;
  return _method->get_Method()->constants()->constant_tag_at(cp_index);
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_raw_pool_tag
//
constantTag ciBytecodeStream::get_raw_pool_tag_at(int index) const {
  VM_ENTRY_MARK;
  return _method->get_Method()->constants()->tag_at(index);
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_basic_type_for_constant_at
//
BasicType ciBytecodeStream::get_basic_type_for_constant_at(int cp_index) const {
  VM_ENTRY_MARK;
  return _method->get_Method()->constants()->basic_type_for_constant_at(cp_index);
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_field_index
//
// If this is a field access bytecode, get the constant pool
// index of the referenced field.
int ciBytecodeStream::get_field_index() {
  assert(cur_bc() == Bytecodes::_getfield ||
         cur_bc() == Bytecodes::_putfield ||
         cur_bc() == Bytecodes::_getstatic ||
         cur_bc() == Bytecodes::_putstatic, "wrong bc");
  return get_index_u2();
}


// ------------------------------------------------------------------
// ciBytecodeStream::get_field
//
// If this bytecode is one of get_field, get_static, put_field,
// or put_static, get the referenced field.
ciField* ciBytecodeStream::get_field(bool& will_link) {
  ciField* f = CURRENT_ENV->get_field_by_index(_holder, get_field_index(), _bc);
  will_link = f->will_link(_method, _bc);
  return f;
}


// ------------------------------------------------------------------
// ciBytecodeStream::get_declared_field_holder
//
// Get the declared holder of the currently referenced field.
//
// Usage note: the holder() of a ciField class returns the canonical
// holder of the field, rather than the holder declared in the
// bytecodes.
//
// There is no "will_link" result passed back.  The user is responsible
// for checking linkability when retrieving the associated field.
ciInstanceKlass* ciBytecodeStream::get_declared_field_holder() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  int holder_index = get_field_holder_index();
  bool ignore;
  return CURRENT_ENV->get_klass_by_index(cpool, holder_index, ignore, _holder)
      ->as_instance_klass();
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_field_holder_index
//
// Get the constant pool index of the declared holder of the field
// referenced by the current bytecode.  Used for generating
// deoptimization information.
int ciBytecodeStream::get_field_holder_index() {
  GUARDED_VM_ENTRY(
    ConstantPool* cpool = _holder->get_instanceKlass()->constants();
    return cpool->klass_ref_index_at(get_field_index(), _bc);
  )
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_method_index
//
// If this is a method invocation bytecode, get the constant pool
// index of the invoked method.
int ciBytecodeStream::get_method_index() {
  assert(Bytecodes::is_invoke(cur_bc()), "invalid bytecode: %s", Bytecodes::name(cur_bc()));
  if (has_index_u4())
    return get_index_u4();  // invokedynamic
  return get_index_u2();
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_method
//
// If this is a method invocation bytecode, get the invoked method.
// Additionally return the declared signature to get more concrete
// type information if required (Cf. invokedynamic and invokehandle).
ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_signature_result) {
  VM_ENTRY_MARK;
  ciEnv* env = CURRENT_ENV;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
  will_link = m->is_loaded();

  // Use the signature stored in the CP cache to create a signature
  // with correct types (in respect to class loaders).
  //
  // In classic Java (before Java 7) there is never the slightest
  // difference between the signature at the call site and that of the
  // method.  Such a difference would have been a type error in the
  // JVM.
  //
  // Now there are a few circumstances where the signature of a call
  // site (which controls the outgoing stacked arguments) can differ
  // from the signature of the method (which controls the receipt of
  // those arguments at the method entry point).
  //
  // A. The signatures can differ if the callee is a static method and
  // the caller thinks it is calling a non-static method (VH.get).
  // This requires the method signature to have an explicit leading
  // argument for the implicit 'this', not present at the call site.
  //
  // B. The call site can have less specific parameter types than the
  // method, allowing loosely-typed code to handle strongly-typed
  // methods.  This happens with linkToStatic and related linker
  // commands.  Obviously the loosely-typed code has to ensure that
  // the strongly typed method's invariants are respected, and this is
  // done by issuing dynamic casts.
  //
  // C. The call site can have more specific parameter types than the
  // method, allowing loosely-typed methods to handle strongly-typed
  // requests.
  //
  // D. There are corresponding effects with return values, such as
  // boolean method returning an int to an int-receiving call site,
  // even though the method thought it returned just a boolean.
  //
  // E. The calling sequence at a particular call site may add an
  // "appendix" argument not mentioned in the call site signature.  It
  // is expected by the method signature, though, and this adds to the
  // method's arity, even after 'this' parameter effects (A) are
  // discounted.  Appendixes are used by invokehandle and
  // invokedynamic instructions.
  //
  // F. A linker method (linkToStatic, etc.) can also take an extra
  // argument, a MemberName which routes the call to a concrete
  // strongly-typed method.  In this case the linker method may also
  // differ in any of the ways A-D.  The eventual method will ignore
  // the presence of the extra argument.
  //
  // None of these changes to calling sequences requires an argument
  // to be moved or reformatted in any way.  This works because all
  // references look alike to the JVM, as do all primitives (except
  // float/long/double).  Another required property of the JVM is
  // that, if a trailing argument is added or dropped, the placement
  // of other arguments does not change.  This allows cases E and F to
  // work smoothly, against without any moving or reformatting,
  // despite the arity change.
  //
  if (has_local_signature()) {
    Symbol* local_signature = cpool->symbol_at(get_method_signature_index(cpool));
    ciSymbol* sig_sym  = env->get_symbol(local_signature);
    ciKlass* pool_holder = env->get_klass(cpool->pool_holder());
    ciSignature* call_site_sig = new (env->arena()) ciSignature(pool_holder, cpool, sig_sym);
    // Examples of how the call site signature can differ from the method's own signature:
    //
    //  meth = static jboolean java.lang.invoke.VarHandleGuards.guard_LII_Z(jobject, jobject, jint, jint, jobject)
    //  msig = (Ljava/lang/invoke/VarHandle;Ljava/lang/Object;IILjava/lang/invoke/VarHandle$AccessDescriptor;)Z
    //  call = (Ljava/util/concurrent/locks/AbstractQueuedSynchronizer;II)Z
    //
    //  meth = static jobject java.lang.invoke.LambdaForm$MH/0x0000000800066840.linkToTargetMethod(jobject, jobject)
    //  msig = (Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;
    //  call = (Ljava/lang/String;)Ljava/util/function/Predicate;
    //
    (*declared_signature_result) = call_site_sig;

  } else {
    // We can just use the method's own signature.  It may differ from the call site, but not by much.
    //
    // Examples of how the call site signature can differ from the method's signature:
    //
    // meth = static final native jint java.lang.invoke.MethodHandle.linkToStatic(jobject, jobject, jint, jint, jobject)
    // msig = (Ljava/lang/Object;Ljava/lang/Object;IILjava/lang/invoke/MemberName;)I
    // call = (Ljava/lang/invoke/VarHandle;Ljava/lang/Object;IILjava/lang/invoke/MemberName;)Z
    //
    // meth = final native jint java.lang.invoke.MethodHandle.invokeBasic(jobject, jobject, jint, jint)
    // msig = (Ljava/lang/Object;Ljava/lang/Object;II)I
    // call = (Ljava/lang/invoke/VarHandle;Ljava/lang/Object;II)Z
    //
    (*declared_signature_result) = m->signature();
  }
  return m;
}

// ------------------------------------------------------------------
// ciBytecodeStream::has_appendix
//
// Returns true if there is an appendix argument stored in the
// constant pool cache at the current bci.
bool ciBytecodeStream::has_appendix() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  return ConstantPool::has_appendix_at_if_loaded(cpool, get_method_index(), cur_bc());
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_appendix
//
// Return the appendix argument stored in the constant pool cache at
// the current bci.
ciObject* ciBytecodeStream::get_appendix() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  oop appendix_oop = ConstantPool::appendix_at_if_loaded(cpool, get_method_index(), cur_bc());
  return CURRENT_ENV->get_object(appendix_oop);
}

// ------------------------------------------------------------------
// ciBytecodeStream::has_local_signature
//
// Returns true if the method stored in the constant
// pool cache at the current bci has a local signature.
bool ciBytecodeStream::has_local_signature() {
  GUARDED_VM_ENTRY(
    constantPoolHandle cpool(Thread::current(), _method->get_Method()->constants());
    return ConstantPool::has_local_signature_at_if_loaded(cpool, get_method_index(), cur_bc());
  )
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_declared_method_holder
//
// Get the declared holder of the currently referenced method.
//
// Usage note: the holder() of a ciMethod class returns the canonical
// holder of the method, rather than the holder declared in the
// bytecodes.
//
// There is no "will_link" result passed back.  The user is responsible
// for checking linkability when retrieving the associated method.
ciKlass* ciBytecodeStream::get_declared_method_holder() {
  VM_ENTRY_MARK;
  constantPoolHandle cpool(THREAD, _method->get_Method()->constants());
  bool ignore;
  // report as MethodHandle for invokedynamic, which is syntactically classless
  if (cur_bc() == Bytecodes::_invokedynamic) {
    return CURRENT_ENV->MethodHandle_klass();
  }
  return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_method_holder_index
//
// Get the constant pool index of the declared holder of the method
// referenced by the current bytecode.  Used for generating
// deoptimization information.
int ciBytecodeStream::get_method_holder_index() {
  ConstantPool* cpool = _method->get_Method()->constants();
  return cpool->klass_ref_index_at(get_method_index(), _bc);
}

// ------------------------------------------------------------------
// ciBytecodeStream::get_method_signature_index
//
// Get the constant pool index of the signature of the method
// referenced by the current bytecode.  Used for generating
// deoptimization information.
int ciBytecodeStream::get_method_signature_index(const constantPoolHandle& cpool) {
  GUARDED_VM_ENTRY(
    const int method_index = get_method_index();
    const int name_and_type_index = cpool->name_and_type_ref_index_at(method_index, _bc);
    return cpool->signature_ref_index_at(name_and_type_index);
  )
}
