blob: 4af8e56cc880f9ea9190c78508b5fe94860fe0c1 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @author Gregory Shimansky
*/
/*
* JVMTI field API
*/
#include "jvmti_direct.h"
#include "Class.h"
#include "object_handles.h"
#include "vm_strings.h"
#include "jvmti_utils.h"
#include "jvmti_internal.h"
#include "cxxlog.h"
#include "suspend_checker.h"
/*
* Get Field Name (and Signature)
*
* For the field indicated by klass and field, return the field
* name via name_ptr and field signature via signature_ptr.
*
* REQUIRED Functionality.
*/
jvmtiError JNICALL
jvmtiGetFieldName(jvmtiEnv* env,
jclass klass,
jfieldID field,
char** name_ptr,
char** signature_ptr,
char** generic_ptr)
{
TRACE2("jvmti.field", "GetFieldName called");
SuspendEnabledChecker sec;
/*
* Check given env & current phase.
*/
jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};
CHECK_EVERYTHING();
if (! is_valid_class_object(klass))
return JVMTI_ERROR_INVALID_CLASS;
if( !field ) return JVMTI_ERROR_INVALID_FIELDID; // (25)
char* fld_name;
char* fld_sig;
Field* fld = reinterpret_cast<Field*>(field);
jvmtiError err;
if( name_ptr )
{
const String* name = fld->get_name();
err = _allocate(name->len + 1, (unsigned char**)(&fld_name));
if(err != JVMTI_ERROR_NONE)
return err;
// copy field name
strcpy(fld_name, name->bytes);
*name_ptr = fld_name;
}
if( signature_ptr )
{
const String* sig = fld->get_descriptor();
err = _allocate(sig->len + 1, (unsigned char**)(&fld_sig));
if(err != JVMTI_ERROR_NONE)
{
if(name_ptr && fld_name)
_deallocate((unsigned char*)fld_name);
return err;
}
// copy field signature
strcpy(fld_sig, sig->bytes);
*signature_ptr = fld_sig;
}
// ppervov: no generic signatures support in VM as of yet
if( generic_ptr )
*generic_ptr = NULL;
return JVMTI_ERROR_NONE;
}
/*
* Get Field Declaring Class
*
* For the field indicated by klass and field return the class
* that defined it via declaring_class_ptr. The declaring class
* will either be klass, a superclass, or an implemented interface.
*
* REQUIRED Functionality.
*/
jvmtiError JNICALL
jvmtiGetFieldDeclaringClass(jvmtiEnv* env,
jclass klass,
jfieldID field,
jclass* declaring_class_ptr)
{
TRACE2("jvmti.field", "GetFieldDeclaringClass called");
SuspendEnabledChecker sec;
/*
* Check given env & current phase.
*/
jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};
CHECK_EVERYTHING();
if (! is_valid_class_object(klass))
return JVMTI_ERROR_INVALID_CLASS;
if( !field ) return JVMTI_ERROR_INVALID_FIELDID;
if( !declaring_class_ptr ) return JVMTI_ERROR_NULL_POINTER;
Class* cls = reinterpret_cast<Field*>(field)->get_class();
ObjectHandle hclss = struct_Class_to_java_lang_Class_Handle(cls);
ObjectHandle newH = NewLocalRef(p_TLS_vmthread->jni_env, hclss);
*declaring_class_ptr = (jclass)newH;
return JVMTI_ERROR_NONE;
}
/*
* Get Field Modifiers
*
* For the field indicated by klass and field return the access
* flags via modifiers_ptr.
*
* REQUIRED Functionality.
*/
jvmtiError JNICALL
jvmtiGetFieldModifiers(jvmtiEnv* env,
jclass klass,
jfieldID field,
jint* modifiers_ptr)
{
TRACE2("jvmti.field", "GetFieldModifiers called");
SuspendEnabledChecker sec;
/*
* Check given env & current phase.
*/
jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};
CHECK_EVERYTHING();
if (! is_valid_class_object(klass))
return JVMTI_ERROR_INVALID_CLASS;
if( !field ) return JVMTI_ERROR_INVALID_FIELDID;
if( !modifiers_ptr ) return JVMTI_ERROR_NULL_POINTER;
*modifiers_ptr = 0;
Field* fld = (Field*)field;
if( fld->is_public() ) *modifiers_ptr |= ACC_PUBLIC;
if( fld->is_private() ) *modifiers_ptr |= ACC_PRIVATE;
if( fld->is_protected() ) *modifiers_ptr |= ACC_PROTECTED;
if( fld->is_static() ) *modifiers_ptr |= ACC_STATIC;
if( fld->is_final() ) *modifiers_ptr |= ACC_FINAL;
if( fld->is_volatile() ) *modifiers_ptr |= ACC_VOLATILE;
if( fld->is_transient() ) *modifiers_ptr |= ACC_TRANSIENT;
return JVMTI_ERROR_NONE;
}
/*
* Is Field Synthetic
*
* For the field indicated by klass and field, return a value
* indicating whether the field is synthetic via is_synthetic_ptr.
* Synthetic fields are generated by the compiler but not present
* in the original source code.
*
* OPTIONAL Functionality.
*/
jvmtiError JNICALL
jvmtiIsFieldSynthetic(jvmtiEnv* env,
jclass klass,
jfieldID field,
jboolean* is_synthetic_ptr)
{
TRACE2("jvmti.field", "IsFieldSynthetic called");
SuspendEnabledChecker sec;
/*
* Check given env & current phase.
*/
jvmtiPhase phases[] = {JVMTI_PHASE_START, JVMTI_PHASE_LIVE};
CHECK_EVERYTHING();
CHECK_CAPABILITY(can_get_synthetic_attribute);
if (! is_valid_class_object(klass))
return JVMTI_ERROR_INVALID_CLASS;
if( !field ) return JVMTI_ERROR_INVALID_FIELDID;
if( !is_synthetic_ptr ) return JVMTI_ERROR_NULL_POINTER;
*is_synthetic_ptr = (jboolean)(reinterpret_cast<Field*>(field)->is_synthetic() ? JNI_TRUE : JNI_FALSE);
return JVMTI_ERROR_NONE;
} // jvmtiIsFieldSynthetic