jdk/src/share/native/common/check_code.c
JNIEXPORT jboolean
VerifyClassForMajorVersion(JNIEnv *env, jclass cb, char *buffer, jint len,
jint major_version)
{
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
context_type context_structure;
context_type *context = &context_structure;
jboolean result = CC_OK;
int i;
int num_methods;
int* code_lengths;
unsigned char** code;
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef DEBUG 時にのみ実行)
---------------------------------------- -}
#ifdef DEBUG
GlobalContext = context;
#endif
{- -------------------------------------------
(1) (局所変数の初期化)
---------------------------------------- -}
memset(context, 0, sizeof(context_type));
context->message = buffer;
context->message_buf_len = len;
context->env = env;
context->class = cb;
/* Set invalid method/field index of the context, in case anyone
calls CCerror */
context->method_index = -1;
context->field_index = -1;
{- -------------------------------------------
(1)
---------------------------------------- -}
/* Don't call CCerror or anything that can call it above the setjmp! */
{- -------------------------------------------
(1) まず setjmp() で大域脱出点を設定した後, 以下の if ブロック内で verification を行う.
(エラーが起こった場合には longjmp() で脱出)
---------------------------------------- -}
if (!setjmp(context->jump_buffer)) {
{- -------------------------------------------
(1.1) (変数宣言など)
---------------------------------------- -}
jclass super;
{- -------------------------------------------
(1.1) (局所変数の初期化) (#TODO)
(エラーが起こった場合は longjmp() で脱出)
---------------------------------------- -}
CCinit(context); /* initialize heap; may throw */
{- -------------------------------------------
(1.1) (局所変数の初期化) (#TODO)
(エラーが起こった場合は longjmp() で脱出)
---------------------------------------- -}
initialize_class_hash(context);
{- -------------------------------------------
(1.1) (局所変数の初期化) (#TODO)
(エラーが起こった場合は, CCout_of_memory() を呼んで longjmp() で脱出)
---------------------------------------- -}
context->major_version = major_version;
context->nconstants = JVM_GetClassCPEntriesCount(env, cb);
context->constant_types = (unsigned char *)
malloc(sizeof(unsigned char) * context->nconstants + 1);
if (context->constant_types == 0)
CCout_of_memory(context);
{- -------------------------------------------
(1.1) (局所変数の初期化) (#TODO)
(エラーが起こった場合は, CCout_of_memory() を呼んで longjmp() で脱出)
---------------------------------------- -}
JVM_GetClassCPTypes(env, cb, context->constant_types);
if (context->constant_types == 0)
CCout_of_memory(context);
{- -------------------------------------------
(1.1) (局所変数の初期化) (#TODO)
---------------------------------------- -}
context->object_info =
make_class_info_from_name(context, "java/lang/Object");
context->string_info =
make_class_info_from_name(context, "java/lang/String");
context->throwable_info =
make_class_info_from_name(context, "java/lang/Throwable");
context->cloneable_info =
make_class_info_from_name(context, "java/lang/Cloneable");
context->serializable_info =
make_class_info_from_name(context, "java/io/Serializable");
context->currentclass_info = make_loadable_class_info(context, cb);
{- -------------------------------------------
(1.1) (局所変数の初期化?) (#TODO)
(エラーが起こった場合は, CCout_of_memory() を呼んで longjmp() で脱出)
---------------------------------------- -}
super = (*env)->GetSuperclass(env, cb);
if (super != 0) {
fullinfo_type *gptr;
int i = 0;
context->superclass_info = make_loadable_class_info(context, super);
while(super != 0) {
jclass tmp_cb = (*env)->GetSuperclass(env, super);
(*env)->DeleteLocalRef(env, super);
super = tmp_cb;
i++;
}
(*env)->DeleteLocalRef(env, super);
super = 0;
/* Can't go on context heap since it survives more than
one method */
context->superclasses = gptr =
malloc(sizeof(fullinfo_type)*(i + 1));
if (gptr == 0) {
CCout_of_memory(context);
}
super = (*env)->GetSuperclass(env, context->class);
while(super != 0) {
jclass tmp_cb;
*gptr++ = make_class_info(context, super);
tmp_cb = (*env)->GetSuperclass(env, super);
(*env)->DeleteLocalRef(env, super);
super = tmp_cb;
}
*gptr = 0;
} else {
context->superclass_info = 0;
}
(*env)->DeleteLocalRef(env, super);
{- -------------------------------------------
(1.1) veirfy 対象クラスの全てのフィールドに対し
verify_field() を呼び出し, verification を行う.
---------------------------------------- -}
/* Look at each method */
for (i = JVM_GetClassFieldsCount(env, cb); --i >= 0;)
verify_field(context, cb, i);
{- -------------------------------------------
(1.1) veirfy 対象クラスの全てのメソッドに対し
verify_method() を呼び出し, verification を行う.
---------------------------------------- -}
num_methods = JVM_GetClassMethodsCount(env, cb);
read_all_code(context, cb, num_methods, &code_lengths, &code);
for (i = num_methods - 1; i >= 0; --i)
verify_method(context, cb, i, code_lengths[i], code[i]);
free_all_code(context, num_methods, code);
{- -------------------------------------------
(1.1) verify 結果は成功(CC_OK)とする
---------------------------------------- -}
result = CC_OK;
{- -------------------------------------------
(1) もし longjmp() で返ってきた場合は,
(エラーが起きているので)
verify 結果として発生したエラーを設定
---------------------------------------- -}
} else {
result = context->err_code;
}
{- -------------------------------------------
(1)
---------------------------------------- -}
/* Cleanup */
finalize_class_hash(context);
while(context->allocated_memory)
pop_and_free(context);
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef DEBUG 時にのみ実行)
---------------------------------------- -}
#ifdef DEBUG
GlobalContext = 0;
#endif
{- -------------------------------------------
(1) 確保したメモリを解放しておく.
---------------------------------------- -}
if (context->exceptions)
free(context->exceptions);
if (context->constant_types)
free(context->constant_types);
if (context->superclasses)
free(context->superclasses);
{- -------------------------------------------
(1) (デバッグ用の処理) (#ifdef DEBUG 時にのみ実行)
---------------------------------------- -}
#ifdef DEBUG
/* Make sure all global refs created in the verifier are freed */
assert(context->n_globalrefs == 0);
#endif
{- -------------------------------------------
(1) 確保したメモリを解放しておく.
---------------------------------------- -}
CCdestroy(context); /* destroy heap */
{- -------------------------------------------
(1) 結果をリターン
---------------------------------------- -}
return result;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.