/* class_loader.h
   Copyright (C) 2005 Free Software Foundation, Inc.

This file is part of Mysaifu JVM

Mysaifu JVM is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 of the License.

Mysaifu JVM 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 for more details.

You should have received a copy of the GNU General Public License
along with GNU Classpath; see the file COPYING.  If not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
02111-1307 USA.
*/

#ifndef CLASS_LOADER_H_INCLUDED
#define CLASS_LOADER_H_INCLUDED

#include "ClassFile.h"
#include "frame.h"
#include "common_funcs.h"

/**
 * staticデータの状態を表す定数
 */
/**
 * エラー状態
 */
#define	STATIC_DATA_ERROR			-1

/**
 * メモリが確保された状態
 */
#define	STATIC_DATA_ALLOCATED		0

/**
 * 初期化中
 */
#define STATIC_DATA_INITIALIZING	1

/**
 * 初期化完了
 */
#define STATIC_DATA_INITIALIZED		2

/**
 * クラスローダ
 * 定義は非公開
 */
struct class_loader;

extern enum VerifyMode;

extern class_loader* g_bootstrap_class_loader;

/**
 * クラスローダ設定を初期化する
 */
void init_class_loader_settings(VerifyMode mode);

/**
 * ブートストラップ・クラスローダを返す
 */
inline class_loader* get_bootstrap_class_loader() {
	return g_bootstrap_class_loader;
}

/**
 * 指定されたClassFile構造体の定義クラスローダを返す
 *
 */
inline class_loader* get_defining_loader(ClassFile* class_file) {
	return class_file->defining_loader;
}

/**
 * プリミティブクラスのClassFile構造体をロードする
 */
ClassFile* load_primitive_ClassFile(frame* frm, const java_utf8* class_name);

/**
 * プリミティブクラスのClassオブジェクトをロードする
 */
jclass find_primitive_class_object(frame* current_frame, jobject static_data);

/**
 * 指定されたClassFile構造体の定義クラスローダを返す
 *
 */
class_loader* get_defining_loader(ClassFile* class_file);

/**
 * 指定されたクラスが同一パッケージに属しているかを返す
 */
bool is_same_package(class_loader* loader, ClassFile* c1, ClassFile* c2);

/**
 * 指定されたClassFileのクラスオブジェクトを検索する
 * 存在していない場合はNULLを返す
 *
 * @param	cfile	検索対象となるClassFile構造体へのポインタ
 * @return	対応するクラスオブジェクト。存在しない場合NULL
 */
jobject get_static_data(ClassFile* cfile);

/**
 * staticデータの状態を返す。
 */
int get_static_data_status(jobject static_data);

/**
 * staticデータの状態を設定する
 */
void set_static_data_status(jobject static_data, int stat);

/**
 * カレントスレッド以外のスレッドがstaticデータを初期化中であるかを
 * 返す。
 */
bool is_another_thread_initializing(jobject static_data);

/**
 * 指定された staticデータに対応する java.lang.Class オブジェクトを返す。
 */
jclass find_class_object(frame* current_frame, jobject static_data, jobject pd);

/**
 * 指定された 名前に対応するロード済み Class オブジェクトを返す。
 * ロードされていない場合はNULLを返す。
 */
jclass find_loaded_class_object(class_loader* loader, frame* current_frame, const java_utf8* name);

/**
 * 指定されたClassLoaderオブジェクトに対応するclass_loader構造体を返す
 */
class_loader* get_class_loader(jobject cl);

/**
 * 指定された class_loader 構造体に対応する java.lang.ClassLoader のインスタンスを返す
 */
jobject get_ClassLoader(class_loader* loader);

/**
 * 指定されたバイト配列を解釈し、ClassFile構造体を生成する。
 * 引数 loader で指定されたクラスローダが、定義クラスローダとして記録される。
 */
ClassFile* define_ClassFile(frame* current_frame,
							const java_utf8* name,
							class_loader* loader,
							const char* buff,
							int offset,
							int length);

/**
 * ブートクラスパスを初期化する
 * 一度設定すると、変更できない。（無視される）
 */
void init_boot_classpath(const _TCHAR* classpath);

/**
 * ブートクラスパスを返す
 */
const _TCHAR* get_boot_classpath();

/**
 * システムクラスパスを初期化する
 * 一度設定すると、変更できない。（無視される）
 */
void init_system_classpath(const _TCHAR* classpath);

/**
 * システムクラスパスを返す
 */
const _TCHAR* get_system_classpath();

/**
 * 指定されたクラスローダを用いて、指定された名前のクラスをロードする
 * 指定されたクラスについての初期化処理（static final フィールドの初期化および<clinit>メソッドの実行）
 * も行われる。
 */
ClassFile* find_ClassFile(frame* frm, class_loader* loader, const java_utf8* class_name);

/**
 * ブートストラップクラスローダを用いて、指定された名前のクラスをロードする
 * 指定されたクラスについての初期化処理（static final フィールドの初期化および<clinit>メソッドの実行）
 * も行われる。
 */
inline ClassFile* find_ClassFile(frame* frm, const java_utf8* class_name) {
	return find_ClassFile(frm, get_bootstrap_class_loader(), class_name);
}

/**
 * 指定されたクラスローダがロードするクラスに対して
 * ベリファイが必要かどうかを返す。
 */
bool needs_verify(class_loader* loader);

/**
 * 指定されたフィールドディスクリプタに関するロード制約を追加する
 */
bool add_loading_constraints_of_field(frame* current_frame, ClassFile* declaring_ClassFile, const java_utf8* field_descriptor);

/**
 * 指定されたメソッドディスクリプタに関するロード制約を追加する
 */
bool add_loading_constraints_of_method(frame* current_frame, ClassFile* declaring_ClassFile, const java_utf8* method_descriptor);

/**
 * 指定されたメソッドディスクリプタに関するロード制約を追加する
 */
bool add_loading_constraints_of_method(frame* current_frame,
									   class_loader* loader1,
									   class_loader* loader2,
									   const java_utf8* descriptor);

/**
 * 指定されたクラスローダが使用するPermanentHeapクラスを返す
 */
PermanentHeap* get_heap_of_class_loader(class_loader* loader);

#endif