hotspot/src/share/vm/prims/jvmtiImpl.cpp
// Checks error conditions:
// JVMTI_ERROR_INVALID_SLOT
// JVMTI_ERROR_TYPE_MISMATCH
// Returns: 'true' - everything is Ok, 'false' - error code
bool VM_GetOrSetLocal::check_slot_type(javaVFrame* jvf) {
{- -------------------------------------------
(1) (変数宣言など)
---------------------------------------- -}
methodOop method_oop = jvf->method();
{- -------------------------------------------
(1)
---------------------------------------- -}
if (!method_oop->has_localvariable_table()) {
// Just to check index boundaries
jint extra_slot = (_type == T_LONG || _type == T_DOUBLE) ? 1 : 0;
if (_index < 0 || _index + extra_slot >= method_oop->max_locals()) {
_result = JVMTI_ERROR_INVALID_SLOT;
return false;
}
return true;
}
{- -------------------------------------------
(1) もし局所変数が1つもなければ, false をリターン.
---------------------------------------- -}
jint num_entries = method_oop->localvariable_table_length();
if (num_entries == 0) {
_result = JVMTI_ERROR_INVALID_SLOT;
return false; // There are no slots
}
{- -------------------------------------------
(1)
---------------------------------------- -}
int signature_idx = -1;
int vf_bci = jvf->bci();
LocalVariableTableElement* table = method_oop->localvariable_table_start();
for (int i = 0; i < num_entries; i++) {
int start_bci = table[i].start_bci;
int end_bci = start_bci + table[i].length;
// Here we assume that locations of LVT entries
// with the same slot number cannot be overlapped
if (_index == (jint) table[i].slot && start_bci <= vf_bci && vf_bci <= end_bci) {
signature_idx = (int) table[i].descriptor_cp_index;
break;
}
}
if (signature_idx == -1) {
_result = JVMTI_ERROR_INVALID_SLOT;
return false; // Incorrect slot index
}
Symbol* sign_sym = method_oop->constants()->symbol_at(signature_idx);
const char* signature = (const char *) sign_sym->as_utf8();
BasicType slot_type = char2type(signature[0]);
switch (slot_type) {
case T_BYTE:
case T_SHORT:
case T_CHAR:
case T_BOOLEAN:
slot_type = T_INT;
break;
case T_ARRAY:
slot_type = T_OBJECT;
break;
};
if (_type != slot_type) {
_result = JVMTI_ERROR_TYPE_MISMATCH;
return false;
}
jobject jobj = _value.l;
if (_set && slot_type == T_OBJECT && jobj != NULL) { // NULL reference is allowed
// Check that the jobject class matches the return type signature.
JavaThread* cur_thread = JavaThread::current();
HandleMark hm(cur_thread);
Handle obj = Handle(cur_thread, JNIHandles::resolve_external_guard(jobj));
NULL_CHECK(obj, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
KlassHandle ob_kh = KlassHandle(cur_thread, obj->klass());
NULL_CHECK(ob_kh, (_result = JVMTI_ERROR_INVALID_OBJECT, false));
if (!is_assignable(signature, Klass::cast(ob_kh()), cur_thread)) {
_result = JVMTI_ERROR_TYPE_MISMATCH;
return false;
}
}
return true;
}
This document is available under the GNU GENERAL PUBLIC LICENSE Version 2.