/*
 * Copyright (c) 2005, 2024, 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.
 *
 */

#ifndef SHARE_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP
#define SHARE_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP

#include "jvmtifiles/jvmtiEnv.hpp"
#include "oops/constantPool.hpp"


class JvmtiConstantPoolReconstituter : public StackObj {
 private:
  int                  _cpool_size;
  ConstantPool::SymbolHash*  _symmap;
  ConstantPool::SymbolHash*  _classmap;
  constantPoolHandle   _cpool;
  InstanceKlass*       _ik;
  jvmtiError           _err;

 protected:
  InstanceKlass*  ik()           { return _ik; };
  constantPoolHandle   cpool()   { return _cpool; };

  u2 symbol_to_cpool_index(Symbol* sym) {
    return _symmap->symbol_to_value(sym);
  }

  u2 class_symbol_to_cpool_index(Symbol* sym) {
    return _classmap->symbol_to_value(sym);
  }

 public:
  // Calls to this constructor must be proceeded by a ResourceMark
  // and a HandleMark
  JvmtiConstantPoolReconstituter(InstanceKlass* ik);

  ~JvmtiConstantPoolReconstituter() {
    if (_symmap != nullptr) {
      delete _symmap;
      _symmap = nullptr;
    }
    if (_classmap != nullptr) {
      delete _classmap;
      _classmap = nullptr;
    }
  }


  void       set_error(jvmtiError err)    { _err = err; }
  jvmtiError get_error()                  { return _err; }

  int cpool_size()                        { return _cpool_size; }

  void copy_cpool_bytes(unsigned char *cpool_bytes) {
    if (cpool_bytes == nullptr) {
      assert(cpool_bytes != nullptr, "cpool_bytes pointer must not be null");
      return;
    }
    cpool()->copy_cpool_bytes(cpool_size(), _symmap, cpool_bytes);
  }
};


class JvmtiClassFileReconstituter : public JvmtiConstantPoolReconstituter {
 private:
  size_t               _buffer_size;
  u1*                  _buffer;
  u1*                  _buffer_ptr;
  Thread*              _thread;

  enum {
    // initial size should be power of two
    initial_buffer_size = 1024
  };

  inline Thread* thread() { return _thread; }

  void write_class_file_format();
  void write_field_infos();
  void write_method_infos();
  void write_method_info(const methodHandle& method);
  void write_code_attribute(const methodHandle& method);
  void write_exceptions_attribute(ConstMethod* const_method);
  void write_method_parameter_attribute(const ConstMethod* const_method);
  void write_synthetic_attribute();
  void write_class_attributes();
  void write_source_file_attribute();
  void write_source_debug_extension_attribute();
  u2 line_number_table_entries(const methodHandle& method);
  void write_line_number_table_attribute(const methodHandle& method, u2 num_entries);
  void write_local_variable_table_attribute(const methodHandle& method, u2 num_entries);
  void write_local_variable_type_table_attribute(const methodHandle& method, u2 num_entries);
  void write_stackmap_table_attribute(const methodHandle& method, int stackmap_table_len);
  u2 inner_classes_attribute_length();
  void write_inner_classes_attribute(int length);
  void write_signature_attribute(u2 generic_signaure_index);
  void write_attribute_name_index(const char* name);
  void write_annotations_attribute(const char* attr_name, AnnotationArray* annos);
  void write_bootstrapmethod_attribute();
  void write_nest_host_attribute();
  void write_nest_members_attribute();
  void write_permitted_subclasses_attribute();
  void write_record_attribute();

  address writeable_address(size_t size);
  void write_u1(u1 x);
  void write_u2(u2 x);
  void write_u4(u4 x);
  void write_u8(u8 x);

 public:
  // Calls to this constructor must be proceeded by a ResourceMark
  // and a HandleMark
  JvmtiClassFileReconstituter(InstanceKlass* ik) :
                                      JvmtiConstantPoolReconstituter(ik) {
    _buffer_size = initial_buffer_size;
    _buffer = _buffer_ptr = NEW_RESOURCE_ARRAY(u1, _buffer_size);
    _thread = Thread::current();
    write_class_file_format();
  };

  size_t class_file_size()    { return _buffer_ptr - _buffer; }

  u1* class_file_bytes()      { return _buffer; }

  static void copy_bytecodes(const methodHandle& method, unsigned char* bytecodes);
};

#endif // SHARE_PRIMS_JVMTICLASSFILERECONSTITUTER_HPP
