harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r480141 [5/38] - in /harmony/enhanced/jdktools/trunk/modules/jpda: ./ doc/ doc/images/ make/ src/ src/common/ src/common/other/ src/common/other/jpda/ src/common/other/jpda/jdwp/ src/common/other/jpda/jdwp/agent/ src/common/other/jpda/jdwp/...
Date Tue, 28 Nov 2006 17:49:31 GMT
Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.cpp?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.cpp (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.cpp Tue Nov 28 09:49:08 2006
@@ -0,0 +1,870 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed 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 Anatoly F. Bondarenko, Viacheslav G. Rybalov
+ * @version $Revision: 1.28 $
+ */
+#include "ObjectReference.h"
+#include "PacketParser.h"
+#include "ObjectManager.h"
+
+using namespace jdwp;
+using namespace ObjectReference;
+
+//------------------------------------------------------------------------------
+//ReferenceTypeHandler(1)-------------------------------------------------------
+
+void
+ObjectReference::ReferenceTypeHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jobject jvmObject = m_cmdParser->command.ReadObjectID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException, JDWP_ERROR_INVALID_OBJECT
+    jclass jvmClass = jni->GetObjectClass(jvmObject); 
+
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afs(signature);
+        JDWP_TRACE_DATA("ReferenceType: received: objectID=" << jvmObject 
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+
+    jboolean isArrayClass;
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->IsArrayClass(jvmClass, &isArrayClass));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+
+    jbyte refTypeTag = JDWP_TYPE_TAG_CLASS;
+    if ( isArrayClass ) {
+        refTypeTag = JDWP_TYPE_TAG_ARRAY;
+    }
+
+    m_cmdParser->reply.WriteByte(refTypeTag);
+    m_cmdParser->reply.WriteReferenceTypeID(jni, jvmClass);
+    JDWP_TRACE_DATA("ReferenceType: send: refTypeTag=" << refTypeTag 
+        << ", refTypeID=" << jvmClass);
+
+} // ReferenceTypeHandler::Execute()
+
+//------------------------------------------------------------------------------
+//GetValuesHandler(2)-----------------------------------------------------------
+
+void
+ObjectReference::GetValuesHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jobject jvmObject = m_cmdParser->command.ReadObjectID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException, JDWP_ERROR_INVALID_OBJECT
+
+    jclass jvmClass = jni->GetObjectClass(jvmObject); 
+    jint fieldsNumber = m_cmdParser->command.ReadInt();
+    // Can be: InternalErrorException
+
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("GetValues: received: objectID=" << jvmObject 
+            << ", classSignature=" << JDWP_CHECK_NULL(signature)
+            << ", fields=" << fieldsNumber);
+    }
+#endif
+
+    jvmtiEnv* jvmti = AgentBase::GetJvmtiEnv();
+
+    m_cmdParser->reply.WriteInt(fieldsNumber);
+    // The number of values returned, always equal to the number of values to get.
+
+    for (int i = 0; i < fieldsNumber; i++) {
+        jfieldID jvmFieldID = m_cmdParser->command.ReadFieldID(jni);
+        // Can be: InternalErrorException, OutOfMemoryException
+
+        // check that given field belongs to class of passed jobject (jvmClass)
+        // taking into account inheritance
+        jvmtiError err;
+        jclass declaringClass;
+        JVMTI_TRACE(err, jvmti->GetFieldDeclaringClass(jvmClass, jvmFieldID,
+            &declaringClass));
+
+        if (err != JVMTI_ERROR_NONE) {
+            throw AgentException(err);
+        }
+
+        if ( jni->IsAssignableFrom(jvmClass, declaringClass) == JNI_FALSE ) {
+            // given field does not belong to class of passed jobject
+            throw AgentException(JDWP_ERROR_INVALID_FIELDID);
+        }
+
+        char* fieldName = 0;
+        char* fieldSignature = 0;
+        JVMTI_TRACE(err, jvmti->GetFieldName(jvmClass, jvmFieldID,
+            &fieldName, &fieldSignature, 0));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID
+            throw AgentException(err);
+        }
+        JvmtiAutoFree autoFreeFieldName(fieldName);
+        JvmtiAutoFree autoFreeFieldSignature(fieldSignature);
+
+        // Check if given field is static
+        jint fieldModifiers;
+        JVMTI_TRACE(err, jvmti->GetFieldModifiers(jvmClass, jvmFieldID,
+            &fieldModifiers));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID,
+            // JVMTI_ERROR_NULL_POINTER
+            throw AgentException(err);
+        }
+
+        jboolean isFieldStatic = JNI_FALSE;
+        if ( (fieldModifiers & ACC_STATIC) != 0 ) { // ACC_STATIC_FLAG = 0x0008;
+            // given field is static
+            isFieldStatic = JNI_TRUE;
+        }
+
+        jvalue fieldValue;
+        jdwpTag fieldValueTag;
+        switch ( fieldSignature[0] ) {
+        case 'Z':
+            fieldValueTag = JDWP_TAG_BOOLEAN;
+            if ( isFieldStatic ) {
+                fieldValue.z = jni->GetStaticBooleanField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(boolean)" << fieldValue.z);
+            } else {
+                fieldValue.z = jni->GetBooleanField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(boolean)" << fieldValue.z);
+            }
+            break;
+        case 'B':
+            fieldValueTag = JDWP_TAG_BYTE;
+            if ( isFieldStatic ) {
+                fieldValue.b = jni->GetStaticByteField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(byte)" << fieldValue.b);
+            } else {
+                fieldValue.b = jni->GetByteField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(byte)" << fieldValue.b);
+            }
+            break;
+        case 'C':
+            fieldValueTag = JDWP_TAG_CHAR;
+            if ( isFieldStatic ) {
+                fieldValue.c = jni->GetStaticCharField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(char)" << fieldValue.c);
+            } else {
+                fieldValue.c = jni->GetCharField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(char)" << fieldValue.c);
+            }
+            break;
+        case 'S':
+            fieldValueTag = JDWP_TAG_SHORT;
+            if ( isFieldStatic ) {
+                fieldValue.s = jni->GetStaticShortField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(short)" << fieldValue.s);
+            } else {
+                fieldValue.s = jni->GetShortField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(short)" << fieldValue.s);
+            }
+            break;
+        case 'I':
+            fieldValueTag = JDWP_TAG_INT;
+            if ( isFieldStatic ) {
+                fieldValue.i = jni->GetStaticIntField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(int)" << fieldValue.i);
+            } else {
+                fieldValue.i = jni->GetIntField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(int)" << fieldValue.i);
+            }
+            break;
+        case 'J':
+            fieldValueTag = JDWP_TAG_LONG;
+            if ( isFieldStatic ) {
+                fieldValue.j = jni->GetStaticLongField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(long)" << fieldValue.l);
+            } else {
+                fieldValue.j = jni->GetLongField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(long)" << fieldValue.l);
+            }
+            break;
+        case 'F':
+            fieldValueTag = JDWP_TAG_FLOAT;
+            if ( isFieldStatic ) {
+                fieldValue.f = jni->GetStaticFloatField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(float)" << fieldValue.f);
+            } else {
+                fieldValue.f = jni->GetFloatField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(float)" << fieldValue.f);
+            }
+            break;
+        case 'D':
+            fieldValueTag = JDWP_TAG_DOUBLE;
+            if ( isFieldStatic ) {
+                fieldValue.d = jni->GetStaticDoubleField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(double)" << fieldValue.d);
+            } else {
+                fieldValue.d = jni->GetDoubleField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(double)" << fieldValue.d);
+            }
+            break;
+        case 'L':
+        case '[':
+            if ( isFieldStatic ) {
+                fieldValue.l = jni->GetStaticObjectField(jvmClass, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(object)" << fieldValue.l);
+            } else {
+                fieldValue.l = jni->GetObjectField(jvmObject, jvmFieldID);
+                JDWP_TRACE_DATA("GetValues: get instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(double)" << fieldValue.l);
+            }
+            fieldValueTag = AgentBase::GetClassManager().GetJdwpTag(jni, fieldValue.l);
+            break;
+        default:
+            // should not reach here
+            JDWP_TRACE_DATA("GetValues: bad field signature: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", signature: " << fieldSignature);
+            throw InternalErrorException();
+        }
+
+        m_cmdParser->reply.WriteValue(jni, fieldValueTag, fieldValue);
+       
+    } // for (int i = 0; i < fieldsNumber; i++) {
+
+} // GetValuesHandler::Execute()
+
+//------------------------------------------------------------------------------
+//SetValuesHandler(3)-----------------------------------------------------------
+
+
+void
+ObjectReference::SetValuesHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jobject jvmObject = m_cmdParser->command.ReadObjectID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_OBJECT
+   
+    jclass jvmClass = jni->GetObjectClass(jvmObject); 
+    jint fieldsNumber = m_cmdParser->command.ReadInt();
+    // Can be: InternalErrorException
+
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afs(signature);
+        JDWP_TRACE_DATA("SetValues: received: objectID=" << jvmObject 
+            << ", classSignature=" << JDWP_CHECK_NULL(signature)
+            << ", fields=" << fieldsNumber);
+    }
+#endif
+
+    jvmtiEnv* jvmti = AgentBase::GetJvmtiEnv();
+    for (int i = 0; i < fieldsNumber; i++) {
+        jfieldID jvmFieldID = m_cmdParser->command.ReadFieldID(jni);
+        // Can be: InternalErrorException, OutOfMemoryException
+
+        // check that given field belongs to class of passed jobject (jvmClass)
+        // taking into account inheritance
+        jvmtiError err;
+        jclass declaringClass;
+        JVMTI_TRACE(err, jvmti->GetFieldDeclaringClass(jvmClass, jvmFieldID,
+            &declaringClass));
+
+        if (err != JVMTI_ERROR_NONE) {
+            throw AgentException(err);
+        }
+
+        if ( jni->IsAssignableFrom(jvmClass, declaringClass) == JNI_FALSE ) {
+            // given field does not belong to class of passed jobject
+            throw AgentException(JDWP_ERROR_INVALID_FIELDID);
+        }
+
+        char* fieldName = 0;
+        char* fieldSignature = 0;
+        JVMTI_TRACE(err, jvmti->GetFieldName(jvmClass, jvmFieldID,
+            &fieldName, &fieldSignature, 0));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID
+            throw AgentException(err);
+        }
+        JvmtiAutoFree autoFreeFieldName(fieldName);
+        JvmtiAutoFree autoFreeFieldSignature(fieldSignature);
+
+        // Check if given field is static
+        jint fieldModifiers;
+        JVMTI_TRACE(err, jvmti->GetFieldModifiers(jvmClass, jvmFieldID,
+            &fieldModifiers));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID,
+            // JVMTI_ERROR_NULL_POINTER
+            throw AgentException(err);
+        }
+
+        jboolean isFieldStatic = JNI_FALSE;
+        if ( (fieldModifiers & ACC_STATIC) != 0 ) { // ACC_STATIC_FLAG = 0x0008;
+            // given field is static
+            isFieldStatic = JNI_TRUE;
+        }
+
+        jdwpTag fieldValueTag 
+            = AgentBase::GetClassManager().GetJdwpTagFromSignature(fieldSignature);
+
+        jvalue fieldValue 
+            = m_cmdParser->command.ReadUntaggedValue(jni, fieldValueTag);
+        // Can be: InternalErrorException, OutOfMemoryException,
+        // JDWP_ERROR_INVALID_OBJECT
+
+        switch ( fieldValueTag ) {
+        case JDWP_TAG_BOOLEAN:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(boolean)" << fieldValue.z);
+                jni->SetStaticBooleanField(jvmClass, jvmFieldID, fieldValue.z);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(boolean)" << fieldValue.z);
+                jni->SetBooleanField(jvmObject, jvmFieldID, fieldValue.z);
+            }
+            break;
+        case JDWP_TAG_BYTE:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(byte)" << fieldValue.b);
+                jni->SetStaticByteField(jvmClass, jvmFieldID, fieldValue.b);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(byte)" << fieldValue.b);
+                jni->SetByteField(jvmObject, jvmFieldID, fieldValue.b);
+            }
+            break;
+        case JDWP_TAG_CHAR:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(char)" << fieldValue.c);
+                jni->SetStaticCharField(jvmClass, jvmFieldID, fieldValue.c);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(char)" << fieldValue.c);
+                jni->SetCharField(jvmObject, jvmFieldID, fieldValue.c);
+            }
+            break;
+        case JDWP_TAG_SHORT:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(short)" << fieldValue.s);
+                jni->SetStaticShortField(jvmClass, jvmFieldID, fieldValue.s);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(short)" << fieldValue.s);
+                jni->SetShortField(jvmObject, jvmFieldID, fieldValue.s);
+            }
+            break;
+        case JDWP_TAG_INT:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(int)" << fieldValue.i);
+                jni->SetStaticIntField(jvmClass, jvmFieldID, fieldValue.i);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(int)" << fieldValue.i);
+                jni->SetIntField(jvmObject, jvmFieldID, fieldValue.i);
+            }
+            break;
+        case JDWP_TAG_LONG:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(long)" << fieldValue.j);
+                jni->SetStaticLongField(jvmClass, jvmFieldID, fieldValue.j);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(long)" << fieldValue.j);
+                jni->SetLongField(jvmObject, jvmFieldID, fieldValue.j);
+            }
+            break;
+        case JDWP_TAG_FLOAT:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(float)" << fieldValue.f);
+                jni->SetStaticFloatField(jvmClass, jvmFieldID, fieldValue.f);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(float)" << fieldValue.f);
+                jni->SetFloatField(jvmObject, jvmFieldID, fieldValue.f);
+            }
+            break;
+        case JDWP_TAG_DOUBLE:
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(double)" << fieldValue.d);
+                jni->SetStaticDoubleField(jvmClass, jvmFieldID, fieldValue.d);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(double)" << fieldValue.d);
+                jni->SetDoubleField(jvmObject, jvmFieldID, fieldValue.d);
+            }
+            break;
+        case JDWP_TAG_OBJECT:
+        case JDWP_TAG_ARRAY:
+            if ( ! AgentBase::GetClassManager().IsObjectValueFitsFieldType
+                    (jni, fieldValue.l, fieldSignature) ) {
+                JDWP_TRACE_DATA("SetValues: bad object type: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", signature=" << fieldSignature
+                    << ", value=(object)" << fieldValue.l);
+                throw AgentException(JDWP_ERROR_INVALID_OBJECT);
+            }
+
+            if ( isFieldStatic ) {
+                JDWP_TRACE_DATA("SetValues: set static: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(object)" << fieldValue.l);
+                jni->SetStaticObjectField(jvmClass, jvmFieldID, fieldValue.l);
+            } else {
+                JDWP_TRACE_DATA("SetValues: set instance: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", value=(object)" << fieldValue.l);
+                jni->SetObjectField(jvmObject, jvmFieldID, fieldValue.l);
+            }
+            break;
+        default:
+            // should not reach here
+            JDWP_TRACE_DATA("SetValues: bad field signature: field#=" << i
+                    << ", fieldID=" << jvmFieldID
+                    << ", signature: " << fieldSignature);
+            throw InternalErrorException();
+        }
+
+    } // for (int i = 0; i < fieldsNumber; i++) {
+
+} // SetValuesHandler::Execute()
+
+//------------------------------------------------------------------------------
+//MonitorInfoHandler(5)---------------------------------------------------------
+
+void
+ObjectReference::MonitorInfoHandler::Execute(JNIEnv *jni)
+    throw (AgentException)
+{
+    jobject jvmObject = m_cmdParser->command.ReadObjectID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_OBJECT
+    JDWP_TRACE_DATA("MonitorInfo: received: objectID=" << jvmObject);
+
+    jvmtiMonitorUsage monitorInfo;
+
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetObjectMonitorUsage(jvmObject,
+        &monitorInfo));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_MUST_POSSESS_CAPABILITY, JVMTI_ERROR_INVALID_OBJECT,
+        // JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+
+    JvmtiAutoFree autoFreeWaiters(monitorInfo.waiters);
+    JvmtiAutoFree autoFreeNotifyWaiters(monitorInfo.notify_waiters);
+
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiThreadInfo info;
+        info.name = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(monitorInfo.owner, &info));
+        JvmtiAutoFree jafInfoName(info.name);
+
+        JDWP_TRACE_DATA("MonitorInfo: send: ownerID=" << monitorInfo.owner 
+            << ", name=" << JDWP_CHECK_NULL(info.name)
+            << ", entry_count=" << monitorInfo.entry_count 
+            << ", waiter_count=" << monitorInfo.waiter_count);
+    }
+#endif
+    
+    m_cmdParser->reply.WriteObjectID(jni, monitorInfo.owner);
+    // jthread - the thread object owning this monitor, or NULL if unused 
+
+    m_cmdParser->reply.WriteInt(monitorInfo.entry_count);
+    // The number of times the owning thread has entered the monitor  
+
+    m_cmdParser->reply.WriteInt(monitorInfo.waiter_count);
+    // The number of threads waiting to own this monitor   
+
+    for (int i = 0; i < monitorInfo.waiter_count; i++) {
+
+#ifndef NDEBUG
+        if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+            jvmtiThreadInfo info;
+            info.name = 0;
+            JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(monitorInfo.waiters[i], &info));
+            JvmtiAutoFree jafInfoName(info.name);
+    
+            JDWP_TRACE_DATA("MonitorInfo: waiter#=" << i 
+                << ", threadID=" << monitorInfo.waiters[i]
+                << ", name=" << JDWP_CHECK_NULL(info.name));
+        }
+#endif
+        
+        m_cmdParser->reply.WriteObjectID(jni, monitorInfo.waiters[i]);
+        // jthread - the thread object waiting this monitor 
+    }
+
+} // MonitorInfoHandler::Execute()
+
+//------------------------------------------------------------------------------
+//DisableCollectionHandler(7)---------------------------------------------------
+
+void
+ObjectReference::DisableCollectionHandler::Execute(JNIEnv *jni)
+    throw (AgentException)
+{
+    ObjectID objectID = m_cmdParser->command.ReadRawObjectID();
+    // Can be: InternalErrorException
+    JDWP_TRACE_DATA("DisableCollection: received: objectID=" << objectID);
+
+    GetObjectManager().DisableCollection(jni, objectID);
+    // Can be: JDWP_ERROR_INVALID_OBJECT, OutOfMemoryException
+    JDWP_TRACE_DATA("DisableCollection: disableCollection");
+
+} // DisableCollectionHandler::Execute()
+
+//------------------------------------------------------------------------------
+//EnableCollectionHandler(8)----------------------------------------------------
+
+void
+ObjectReference::EnableCollectionHandler::Execute(JNIEnv *jni)
+    throw (AgentException)
+{
+    ObjectID objectID = m_cmdParser->command.ReadRawObjectID();
+    // Can be: InternalErrorException
+    JDWP_TRACE_DATA("EnableCollection: received: objectID=" << objectID);
+
+    GetObjectManager().EnableCollection(jni, objectID);
+    // Can be: OutOfMemoryException
+    JDWP_TRACE_DATA("EnableCollection: enableCollection");
+
+} // EnableCollectionHandler::Execute()
+
+//------------------------------------------------------------------------------
+//IsCollectedHandler(9)---------------------------------------------------
+
+void
+ObjectReference::IsCollectedHandler::Execute(JNIEnv *jni)
+    throw (AgentException)
+{
+    ObjectID objectID = m_cmdParser->command.ReadRawObjectID();
+    // Can be: InternalErrorException
+    JDWP_TRACE_DATA("IsCollected: received: objectID=" << objectID);
+
+    jboolean isCollected = GetObjectManager().IsCollected(jni, objectID);
+    // Can be: JDWP_ERROR_INVALID_OBJECT
+
+    m_cmdParser->reply.WriteBoolean(isCollected);
+    // Can be: OutOfMemoryException
+    JDWP_TRACE_DATA("IsCollected: send: isCollected=" << isCollected);
+
+} // IsCollectedHandler::Execute()
+
+//------------------------------------------------------------------------------
+//InvokeMethodHandler(6)---------------------------------------------------
+
+const char* ObjectReference::InvokeMethodHandler::GetThreadName() {
+    return "_jdwp_ObjectReference_InvokeMethodHandler";
+}
+
+void 
+ObjectReference::InvokeMethodHandler::Execute(JNIEnv *jni) throw(AgentException) 
+{
+    m_object = m_cmdParser->command.ReadObjectID(jni);
+    m_thread = m_cmdParser->command.ReadThreadID(jni);
+    m_clazz = m_cmdParser->command.ReadReferenceTypeID(jni);
+    m_methodID = m_cmdParser->command.ReadMethodID(jni);
+    int arguments = m_cmdParser->command.ReadInt();
+
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(m_clazz, &signature, 0));
+        JvmtiAutoFree afs(signature);
+        jvmtiThreadInfo threadInfo;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetThreadInfo(m_thread, &threadInfo));
+        JvmtiAutoFree aftn(threadInfo.name);
+        char* methodName = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodName(m_methodID, &methodName, 0, 0));
+        JvmtiAutoFree afmn(methodName);
+        JDWP_TRACE_DATA("InvokeMethod: received: objectID=" << m_object
+            << ", classSignature=" << JDWP_CHECK_NULL(signature) 
+            << ", threadName=" << JDWP_CHECK_NULL(threadInfo.name)
+            << ", classID=" << m_clazz
+            << ", methodName=" << JDWP_CHECK_NULL(methodName)
+            << ", arguments=" << arguments);
+    }
+#endif
+
+    if (AgentBase::GetClassManager().IsClass(jni, m_clazz) != JNI_TRUE) {
+        throw AgentException(JDWP_ERROR_INVALID_CLASS);
+    }
+    
+    char* signature = 0;
+    char* name = 0;
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetMethodName(m_methodID,
+        &name, &signature, 0 /*&generic signature*/));
+    if (err != JVMTI_ERROR_NONE) {
+        throw AgentException(err);
+    }
+    JvmtiAutoFree afv2(signature);
+    JvmtiAutoFree afv3(name);
+
+    JDWP_ASSERT(signature[0] == '(');
+    JDWP_ASSERT(strlen(signature) >= 3);
+    JDWP_ASSERT(signature + strlen(signature) >= strchr(signature, ')'));
+
+    int methodArguments = getArgsNumber(signature);
+
+    if (arguments != methodArguments) {
+        throw AgentException(JDWP_ERROR_ILLEGAL_ARGUMENT);
+    }
+    if (arguments != 0) {
+        m_methodValues = 
+            reinterpret_cast<jvalue*>(AgentBase::GetMemoryManager().Allocate(sizeof(jvalue) * arguments JDWP_FILE_LINE));
+    } else {
+        m_methodValues = 0;
+    }
+    AgentAutoFree afv1(m_methodValues JDWP_FILE_LINE);
+
+    m_returnValue.tag = static_cast<jdwpTag>(*(strchr(signature, ')') + 1));
+    for (int i = 0; i < arguments; i++) {
+        jdwpTaggedValue tValue = m_cmdParser->command.ReadValue(jni);
+        if (IsArgValid(jni, i, tValue, signature) != JNI_TRUE) {
+            JDWP_TRACE_DATA("InvokeMethod: bad argument " << i << ": sig=" << signature);
+            throw AgentException(JDWP_ERROR_TYPE_MISMATCH);
+        }
+        m_methodValues[i] = tValue.value;
+    }
+    m_invokeOptions = m_cmdParser->command.ReadInt();
+
+    m_returnError = JDWP_ERROR_NONE;
+    m_returnException = 0;
+
+    WaitDeferredInvocation(jni);
+
+    if (m_returnError == JDWP_ERROR_NONE) {
+        m_cmdParser->reply.WriteValue(jni, m_returnValue.tag, m_returnValue.value);
+        m_cmdParser->reply.WriteTaggedObjectID(jni, m_returnException);
+    }
+    
+    switch (m_returnValue.tag) {
+    case JDWP_TAG_OBJECT:
+    case JDWP_TAG_ARRAY:
+    case JDWP_TAG_STRING:
+    case JDWP_TAG_THREAD:
+    case JDWP_TAG_THREAD_GROUP:
+    case JDWP_TAG_CLASS_LOADER:
+    case JDWP_TAG_CLASS_OBJECT:
+        if (m_returnValue.value.l != 0) {
+            jni->DeleteGlobalRef(m_returnValue.value.l);
+        }
+        break;
+    default:
+        break;
+    }
+    if (m_returnException != 0) {
+        jni->DeleteGlobalRef(m_returnException);
+    }
+
+    if (m_returnError != JDWP_ERROR_NONE) {
+        throw AgentException(m_returnError);
+    }
+    
+    JDWP_LOG("InvokeMethod: return: method=" << JDWP_CHECK_NULL(name) 
+        << ", sig=" << JDWP_CHECK_NULL(signature) 
+        << ", thread=" << m_thread 
+        << ", returnValueTag=" << m_returnValue.tag
+        << ", returnException=" << m_returnException);
+
+}
+
+void 
+ObjectReference::InvokeMethodHandler::ExecuteDeferredFunc(JNIEnv *jni)
+{
+    JDWP_ASSERT(m_returnValue.tag != 0);
+    JDWP_ASSERT(m_methodID != 0);
+    JDWP_ASSERT(jni != 0);
+    if ((m_invokeOptions & JDWP_INVOKE_NONVIRTUAL) != 0) {
+        JDWP_ASSERT(m_clazz != 0);
+        switch (m_returnValue.tag) {
+        case JDWP_TAG_BOOLEAN:
+            m_returnValue.value.z = jni->CallNonvirtualBooleanMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_BYTE:
+            m_returnValue.value.b = jni->CallNonvirtualByteMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_CHAR:
+            m_returnValue.value.c = jni->CallNonvirtualCharMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_SHORT:
+            m_returnValue.value.s = jni->CallNonvirtualShortMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_INT:
+            m_returnValue.value.i = jni->CallNonvirtualIntMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_LONG:
+            m_returnValue.value.j = jni->CallNonvirtualLongMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_FLOAT:
+            m_returnValue.value.f = jni->CallNonvirtualFloatMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_DOUBLE:
+            m_returnValue.value.d = jni->CallNonvirtualDoubleMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_VOID:
+            jni->CallNonvirtualVoidMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_OBJECT:
+            m_returnValue.value.l =
+                jni->CallNonvirtualObjectMethodA(m_object, m_clazz, m_methodID, m_methodValues);
+            if (m_returnValue.value.l != 0) {
+                m_returnValue.value.l = jni->NewGlobalRef(m_returnValue.value.l);
+                if (m_returnValue.value.l == 0) {
+                    m_returnError = JDWP_ERROR_OUT_OF_MEMORY;
+                }
+            }
+            m_returnValue.tag = GetClassManager().GetJdwpTag(jni, m_returnValue.value.l);
+            break;
+        default:
+            m_returnError = JDWP_ERROR_INVALID_TAG;
+            return;
+        }
+    } else {
+        switch (m_returnValue.tag) {
+        case JDWP_TAG_BOOLEAN:
+            m_returnValue.value.z = jni->CallBooleanMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_BYTE:
+            m_returnValue.value.b = jni->CallByteMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_CHAR:
+            m_returnValue.value.c = jni->CallCharMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_SHORT:
+            m_returnValue.value.s = jni->CallShortMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_INT:
+            m_returnValue.value.i = jni->CallIntMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_LONG:
+            m_returnValue.value.j = jni->CallLongMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_FLOAT:
+            m_returnValue.value.f = jni->CallFloatMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_DOUBLE:
+            m_returnValue.value.d = jni->CallDoubleMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_VOID:
+            jni->CallVoidMethodA(m_object, m_methodID, m_methodValues);
+            break;
+        case JDWP_TAG_OBJECT:
+            m_returnValue.value.l =
+                jni->CallObjectMethodA(m_object, m_methodID, m_methodValues);
+            if (m_returnValue.value.l != 0) {
+                m_returnValue.value.l = jni->NewGlobalRef(m_returnValue.value.l);
+                if (m_returnValue.value.l == 0) {
+                    m_returnError = JDWP_ERROR_OUT_OF_MEMORY;
+                }
+            }
+            m_returnValue.tag = GetClassManager().GetJdwpTag(jni, m_returnValue.value.l);
+            break;
+        default:
+            m_returnError = JDWP_ERROR_INVALID_TAG;
+            return;
+        }
+    }
+    m_returnException = jni->ExceptionOccurred();
+    if (m_returnException != 0) {
+        m_returnException =
+            static_cast<jthrowable>(jni->NewGlobalRef(m_returnException));
+        if (m_returnException == 0) {
+            m_returnError = JDWP_ERROR_OUT_OF_MEMORY;
+        }
+    }
+    jni->ExceptionClear();
+}

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.h
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.h?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.h (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.h Tue Nov 28 09:49:08 2006
@@ -0,0 +1,219 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, 
+ * as applicable.
+ *
+ *  Licensed 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 Anatoly F. Bondarenko, Viacheslav G. Rybalov
+ * @version $Revision: 1.7.2.1 $
+ */
+
+/**
+ * @file
+ * ObjectReference.h
+ *
+ */
+
+#ifndef _OBJECT_REFERENCE_H_
+#define _OBJECT_REFERENCE_H_
+
+#include "AgentException.h"
+#include "CommandHandler.h"
+#include "ClassManager.h"
+#include "ThreadManager.h"
+
+namespace jdwp {
+
+    /**
+     * The namespace includes declaration of the classes implementing commands
+     * from the <code>ObjectReference</code> command set.
+     */
+    namespace ObjectReference {
+        
+    // =========================================================================
+        /**
+         * The class implements the <code>ReferenceType (1)</code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class ReferenceTypeHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>ReferenceType</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // ReferenceTypeHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>GetValues (2)</code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class GetValuesHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>GetValues</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // GetValuesHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>SetValues (3) </code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class SetValuesHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>SetValues</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // SetValuesHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>MonitorInfo (5)</code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class MonitorInfoHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>MonitorInfo</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // MonitorInfoHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>DisableCollection (7)</code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class DisableCollectionHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>DisableCollection</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // DisableCollectionHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>EnableCollection (8) </code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class EnableCollectionHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>EnableCollection</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // EnableCollectionHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>IsCollected (9) </code>
+         * command from the <code>ObjectReference</code> command set.
+         */
+        class IsCollectedHandler : public SyncCommandHandler {
+        protected:
+
+            /**
+             * Executes the <code>IsCollected</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        }; // IsCollectedHandler class
+
+    // =========================================================================
+        /**
+         * The class implements the <code>InvokeMethod</code> command from the
+         * <code>ObjectReference</code> command set.
+         */
+        class InvokeMethodHandler : public SpecialAsyncCommandHandler {
+        public:
+
+            /**
+             * The given method makes deferred checks, executes 
+             * <code>InvokeMethod</code> and should be called from 
+             * the appropriate thread.
+             */
+            virtual void ExecuteDeferredFunc(JNIEnv *jni);
+
+            /**
+             * Gets a thread name for asynchronous execution of the given command handler.
+             *
+             * @return Thread name string.
+             */
+            virtual const char* GetThreadName();
+
+        protected:
+
+            /**
+             * Executes the <code>InvokeMethod</code> JDWP command for the
+             * <code>ObjectReference</code> command set.
+             *
+             * @param jni - the JNI interface pointer
+             */
+            virtual void Execute(JNIEnv *jni) throw(AgentException);
+
+        private:
+            jclass m_clazz;
+            jobject m_object;
+            jmethodID m_methodID;
+            jvalue* m_methodValues;
+
+            jdwpTaggedValue m_returnValue;
+            jthrowable m_returnException;
+
+        };//InvokeMethodHandler
+
+    } // ObjectReference namespace
+
+} // jdwp namespace
+
+#endif //_OBJECT_REFERENCE_H_

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ObjectReference.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ReferenceType.cpp
URL: http://svn.apache.org/viewvc/harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ReferenceType.cpp?view=auto&rev=480141
==============================================================================
--- harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ReferenceType.cpp (added)
+++ harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ReferenceType.cpp Tue Nov 28 09:49:08 2006
@@ -0,0 +1,850 @@
+/*
+ * Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed 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 Anatoly F. Bondarenko
+ * @version $Revision: 1.18.2.1 $
+ */
+#include "ReferenceType.h"
+#include "PacketParser.h"
+#include "ClassManager.h"
+#include <cstring>
+
+using namespace jdwp;
+using namespace ReferenceType;
+
+//------------------------------------------------------------------------------
+//SignatureFileHandler(1)----------------------------------------------------------
+
+void
+ReferenceType::SignatureHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+    JDWP_TRACE_DATA("Signature: received: refTypeID=" << jvmClass);
+
+    char* classSignature = 0;
+    char* classGenericSignature = 0;
+    char** genericSignaturePtr = 0;
+
+    if ( m_withGeneric ) {
+        genericSignaturePtr = &classGenericSignature;
+    }
+
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass,
+        &classSignature, genericSignaturePtr));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_INVALID_CLASS
+        throw AgentException(err);
+    }
+
+    JvmtiAutoFree autoFreeSignature(classSignature);
+    JvmtiAutoFree autoFreeGenericSignature(classGenericSignature);
+
+    m_cmdParser->reply.WriteString(classSignature);
+    if ( m_withGeneric ) {
+        if (classGenericSignature != 0) {
+            m_cmdParser->reply.WriteString(classGenericSignature);
+        } else {
+            m_cmdParser->reply.WriteString("");
+        }
+    }
+    JDWP_TRACE_DATA("Signature: send: classSignature=" << JDWP_CHECK_NULL(classSignature) 
+        << ", classGenericSignature=" << JDWP_CHECK_NULL(classGenericSignature));
+
+} // SignatureHandler::Execute()
+
+//------------------------------------------------------------------------------
+//ClassLoaderHandler(2)----------------------------------------------------------
+
+void
+ReferenceType::ClassLoaderHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("ClassLoader: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+
+    jobject jvmClassLoader;
+
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetClassLoader(jvmClass, &jvmClassLoader));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    // if GetClassLoader() returns NULL value for jvmClassLoader
+    // consider it as the class loader for the jvmClass is the system class
+    // loader and write in reply NULL value which will be mapped
+    // to JDWP_OBJECT_ID_NULL value.
+
+    m_cmdParser->reply.WriteObjectID(jni, jvmClassLoader);
+    JDWP_TRACE_DATA("ClassLoader: send: classLoaderID=" << jvmClassLoader);  
+
+} // ClassLoaderHandler::Execute()
+
+//------------------------------------------------------------------------------
+//ModifiersHandler(3)----------------------------------------------------------
+
+void
+ReferenceType::ModifiersHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("Modifiers: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+    jint jvmClassModifiers;
+
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetClassModifiers(jvmClass,
+        &jvmClassModifiers));
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+
+    m_cmdParser->reply.WriteInt(jvmClassModifiers);
+    JDWP_TRACE_DATA("Modifiers: send: modBits=" << hex << jvmClassModifiers); 
+
+} // ModifiersHandler::Execute()
+
+//------------------------------------------------------------------------------
+//FieldsHandler(4,14)----------------------------------------------------------
+
+void
+ReferenceType::FieldsHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("Fields: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+  
+    jvmtiEnv* jvmti = AgentBase::GetJvmtiEnv();
+
+    jint fieldsCount = 0;
+    jfieldID* fields = 0;
+    jvmtiError err;
+    JVMTI_TRACE(err, jvmti->GetClassFields(jvmClass, &fieldsCount, &fields));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_CLASS_NOT_PREPARED, JVMTI_ERROR_INVALID_CLASS
+        // JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeFields(fields);
+
+    m_cmdParser->reply.WriteInt(fieldsCount);
+    JDWP_TRACE_DATA("Fields: fieldCount=" << fieldsCount);
+    for (int i = 0; i < fieldsCount; i++) {
+        jfieldID jvmFieldID = fields[i];
+        m_cmdParser->reply.WriteFieldID(jni, jvmFieldID);
+
+        char* fieldName = 0;
+        char* fieldSignature = 0;
+        char* genericSignature = 0;
+        char** genericSignaturePtr = 0;
+        if ( m_withGeneric ) {
+            genericSignaturePtr = &genericSignature;
+        }
+
+        JVMTI_TRACE(err, jvmti->GetFieldName(jvmClass, jvmFieldID, &fieldName,
+            &fieldSignature, genericSignaturePtr));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID
+            throw AgentException(err);
+        }
+
+        JvmtiAutoFree autoFreeFieldName(fieldName);
+        JvmtiAutoFree autoFreeFieldSignature(fieldSignature);
+        JvmtiAutoFree autoFreeGenericSignature(genericSignature);
+
+        m_cmdParser->reply.WriteString(fieldName);
+    
+        m_cmdParser->reply.WriteString(fieldSignature);
+
+        if ( m_withGeneric ) {
+            if (genericSignature != 0) {
+                m_cmdParser->reply.WriteString(genericSignature);
+            } else {
+                m_cmdParser->reply.WriteString("");
+            }
+        }
+       
+        jint fieldModifiers;
+        JVMTI_TRACE(err, jvmti->GetFieldModifiers(jvmClass, jvmFieldID,
+            &fieldModifiers));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID,
+            // JVMTI_ERROR_NULL_POINTER
+            throw AgentException(err);
+        }
+
+        jint fieldSyntheticFlag = 0xf0000000;
+        jboolean isFieldSynthetic;
+        JVMTI_TRACE(err, jvmti->IsFieldSynthetic(jvmClass, jvmFieldID,
+            &isFieldSynthetic));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_MUST_POSSESS_CAPABILITY,JVMTI_ERROR_INVALID_CLASS,
+            // JVMTI_ERROR_INVALID_FIELDID, JVMTI_ERROR_NULL_POINTER
+            if (err == JVMTI_ERROR_MUST_POSSESS_CAPABILITY) {
+                fieldSyntheticFlag = 0;
+            } else {
+                throw AgentException(err);
+            }
+        } else {
+            if ( ! isFieldSynthetic ) {
+                fieldSyntheticFlag = 0;
+            }
+        }
+
+        fieldModifiers = fieldModifiers | fieldSyntheticFlag;
+        m_cmdParser->reply.WriteInt(fieldModifiers);
+        JDWP_TRACE_DATA("Fields: send: field#=" << i 
+            << ", fieldsName=" << JDWP_CHECK_NULL(fieldName) 
+            << ", fieldSignature=" << JDWP_CHECK_NULL(fieldSignature) 
+            << ", genericSignature=" << JDWP_CHECK_NULL(genericSignature) 
+            << ", fieldModifiers=" << hex << fieldModifiers);         
+
+     } // for (int i = 0; i < fieldsCount; i++)
+
+} // FieldsHandler::Execute()
+
+//------------------------------------------------------------------------------
+//MethodsHandler(5,15)----------------------------------------------------------
+
+void
+ReferenceType::MethodsHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("Methods: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));  
+    }
+#endif
+    jvmtiEnv* jvmti = AgentBase::GetJvmtiEnv();
+
+    jint methodsCount = 0;
+    jmethodID* methods = 0;
+    jvmtiError err;
+    JVMTI_TRACE(err, jvmti->GetClassMethods(jvmClass, &methodsCount, &methods));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_CLASS_NOT_PREPARED, JVMTI_ERROR_INVALID_CLASS,
+        // JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeFields(methods);
+
+    m_cmdParser->reply.WriteInt(methodsCount);
+    JDWP_TRACE_DATA("Methods: methodCount=" << methodsCount);
+
+    for (int i = 0; i < methodsCount; i++) {
+        jmethodID jvmMethodID = methods[i];
+        m_cmdParser->reply.WriteMethodID(jni, jvmMethodID);
+
+        char* methodName = 0;
+        char* methodSignature = 0;
+        char* genericSignature = 0;
+        char** genericSignaturePtr = 0;
+        if ( m_withGeneric ) {
+            genericSignaturePtr = &genericSignature;
+        }
+
+        JVMTI_TRACE(err, jvmti->GetMethodName(jvmMethodID, &methodName,
+            &methodSignature, genericSignaturePtr));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_METHODID
+            throw AgentException(err);
+        }
+        JvmtiAutoFree autoFreeFieldName(methodName);
+        JvmtiAutoFree autoFreeMethodSignature(methodSignature);
+        JvmtiAutoFree autoFreeGenericSignature(genericSignature);
+
+        m_cmdParser->reply.WriteString(methodName);
+    
+        m_cmdParser->reply.WriteString(methodSignature);
+
+        if ( m_withGeneric ) {
+            if (genericSignature != 0) {
+                m_cmdParser->reply.WriteString(genericSignature);
+            } else {
+                m_cmdParser->reply.WriteString("");
+            }
+        }
+
+        jint methodModifiers;
+        JVMTI_TRACE(err, jvmti->GetMethodModifiers(jvmMethodID,
+            &methodModifiers));
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_METHODID, JVMTI_ERROR_NULL_POINTER
+            throw AgentException(err);
+        }
+
+        jint methodSyntheticFlag = 0xf0000000;
+        jboolean isMethodSynthetic;
+        JVMTI_TRACE(err, jvmti->IsMethodSynthetic(jvmMethodID,
+            &isMethodSynthetic));
+
+        if (err == JVMTI_ERROR_MUST_POSSESS_CAPABILITY) {
+            methodSyntheticFlag = 0;
+        } else {
+            if (err != JVMTI_ERROR_NONE) {
+               // Can be: JVMTI_ERROR_INVALID_METHODID, JVMTI_ERROR_NULL_POINTER
+                throw AgentException(err);
+            }
+            if ( ! isMethodSynthetic ) {
+                methodSyntheticFlag = 0;
+            }
+        }
+
+        methodModifiers = methodModifiers | methodSyntheticFlag;
+        m_cmdParser->reply.WriteInt(methodModifiers);
+        JDWP_TRACE_DATA("Methods: send: method#="<< i 
+            << ", methodName=" << JDWP_CHECK_NULL(methodName) 
+            << ", methodSignature=" << JDWP_CHECK_NULL(methodSignature) 
+            << ", genericSignature=" << JDWP_CHECK_NULL(genericSignature) 
+            << ", methodModifiers=" << hex << methodModifiers);         
+
+    } // for (int i = 0; i < methodsCount; i++)
+
+} // MethodsHandler::Execute()
+
+//------------------------------------------------------------------------------
+//GetValuesHandler(6)-----------------------------------------------------------
+
+void
+ReferenceType::GetValuesHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+
+    jint fieldsNumber = m_cmdParser->command.ReadInt();
+    // Can be: InternalErrorException
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("GetValues: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature) 
+            << ", fields=" << fieldsNumber);
+    }
+#endif
+
+    m_cmdParser->reply.WriteInt(fieldsNumber);
+    // The number of values returned, always equal to the number of values to get.
+
+    jvmtiEnv* jvmti = AgentBase::GetJvmtiEnv();
+
+    for (int i = 0; i < fieldsNumber; i++) {
+        jfieldID jvmFieldID = m_cmdParser->command.ReadFieldID(jni);
+        // Can be: InternalErrorException, OutOfMemoryException
+
+        // check that given field belongs to passed jvmClass
+        // taking into account inheritance
+        jvmtiError err;
+        jclass declaringClass;
+        JVMTI_TRACE(err, jvmti->GetFieldDeclaringClass(jvmClass, jvmFieldID,
+            &declaringClass));
+
+        if (err != JVMTI_ERROR_NONE) {
+            throw AgentException(err);
+        }
+
+        if ( jni->IsAssignableFrom(jvmClass, declaringClass) == JNI_FALSE ) {
+            // given field does not belong to passed jvmClass
+            throw AgentException(JDWP_ERROR_INVALID_FIELDID);
+        }
+
+        jint fieldModifiers;
+        JVMTI_TRACE(err, jvmti->GetFieldModifiers(jvmClass, jvmFieldID,
+            &fieldModifiers));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID,
+            // JVMTI_ERROR_NULL_POINTER
+            throw AgentException(err);
+        }
+
+        if ( (fieldModifiers & 0x0008) == 0 ) { // ACC_STATIC_FLAG = 0x0008;
+            // given field is not static
+            throw AgentException(JDWP_ERROR_INVALID_FIELDID);
+        }
+
+        char* fieldName = 0;
+        char* fieldSignature = 0;
+        JVMTI_TRACE(err, jvmti->GetFieldName(jvmClass, jvmFieldID,
+            &fieldName, &fieldSignature, 0));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_INVALID_FIELDID
+            throw AgentException(err);
+        }
+        JvmtiAutoFree autoFreeFieldName(fieldName);
+        JvmtiAutoFree autoFreeFieldSignature(fieldSignature);
+
+        jvalue fieldValue;
+        jdwpTag fieldValueTag;
+        jobject jobj = NULL;
+        switch ( fieldSignature[0] ) {
+            case 'Z':
+                fieldValueTag = JDWP_TAG_BOOLEAN;
+                fieldValue.z = jni->GetStaticBooleanField(jvmClass, jvmFieldID);
+                break;
+            case 'B':
+                fieldValueTag = JDWP_TAG_BYTE;
+                fieldValue.b = jni->GetStaticByteField(jvmClass, jvmFieldID);
+                break;
+            case 'C':
+                fieldValueTag = JDWP_TAG_CHAR;
+                fieldValue.c = jni->GetStaticCharField(jvmClass, jvmFieldID);
+                break;
+            case 'S':
+                fieldValueTag = JDWP_TAG_SHORT;
+                fieldValue.s = jni->GetStaticShortField(jvmClass, jvmFieldID);
+                break;
+            case 'I':
+                fieldValueTag = JDWP_TAG_INT;
+                fieldValue.i = jni->GetStaticIntField(jvmClass, jvmFieldID);
+                break;
+            case 'J':
+                fieldValueTag = JDWP_TAG_LONG;
+                fieldValue.j = jni->GetStaticLongField(jvmClass, jvmFieldID);
+                break;
+            case 'F':
+                fieldValueTag = JDWP_TAG_FLOAT;
+                fieldValue.f = jni->GetStaticFloatField(jvmClass, jvmFieldID);
+                break;
+            case 'D':
+                fieldValueTag = JDWP_TAG_DOUBLE;
+                fieldValue.d = jni->GetStaticDoubleField(jvmClass, jvmFieldID);
+                break;
+            case 'L':
+            case '[':
+                jobj = jni->GetStaticObjectField(jvmClass, jvmFieldID);
+                fieldValueTag = AgentBase::GetClassManager().GetJdwpTag(jni, jobj);
+                fieldValue.l = jobj;
+                break;
+            default:
+                JDWP_TRACE_DATA("GetValues: unknown field signature: " 
+                    << JDWP_CHECK_NULL(fieldSignature));
+                throw InternalErrorException();
+        }
+        
+        m_cmdParser->reply.WriteValue(jni, fieldValueTag, fieldValue);
+        JDWP_TRACE_DATA("GetValues: send: field#=" << i 
+            << ", fieldName=" << JDWP_CHECK_NULL(fieldName) 
+            << ", fieldSignature=" << JDWP_CHECK_NULL(fieldSignature) 
+            << ", fieldValueTag=" << fieldValueTag);         
+
+    } // for (int i = 0; i < fieldsNumber; i++) {
+
+} // GetValuesHandler::Execute()
+
+//------------------------------------------------------------------------------
+//SourceFileHandler(7)----------------------------------------------------------
+
+void
+ReferenceType::SourceFileHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("SourceFile: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+    char* sourceFileName = 0;
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetSourceFileName(jvmClass,
+        &sourceFileName));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_MUST_POSSESS_CAPABILITY, JVMTI_ERROR_ABSENT_INFORMATION,
+        // JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeFieldName(sourceFileName);
+
+    m_cmdParser->reply.WriteString(sourceFileName);
+    JDWP_TRACE_DATA("SourceFile: send: sourceFile=" << JDWP_CHECK_NULL(sourceFileName));
+
+} // SourceFileHandler::Execute()
+
+//------------------------------------------------------------------------------
+//NestedTypesHandler(8)---------------------------------------------------------
+
+// For reference:
+// 1. JDWP spec:
+// ReferenceType Command Set (2), NestedTypes Command (8):
+// Returns the classes and interfaces directly nested within this type.Types 
+// further nested within those types are not included
+// 2.
+// The Java Language Specification, CHAPTER 8, Classes:
+// A nested class is any class whose declaration occurs within the body of
+// another class or interface.
+// CHAPTER 9, Interfaces:
+// A nested interface is any interface whose declaration occurs within the body
+// of another class or interface
+
+void
+ReferenceType::NestedTypesHandler::Execute(JNIEnv *jni)
+        throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("NestedTypes: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+    char* jvmClassSignature = 0;
+
+    jvmtiEnv* jvmti = AgentBase::GetJvmtiEnv();
+
+    jvmtiError err;
+    JVMTI_TRACE(err, jvmti->GetClassSignature(jvmClass, &jvmClassSignature, 0));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_INVALID_CLASS
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeSignature(jvmClassSignature);
+    size_t jvmClassSignatureLength = strlen(jvmClassSignature);
+
+    jint allClassesCount = 0;
+    jclass* allClasses = 0;
+    JVMTI_TRACE(err, jvmti->GetLoadedClasses(&allClassesCount, &allClasses));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeAllClasses(allClasses);
+
+    /* Since JVMTI doesn't support getting nested classes so here 
+     * following algorithm is used:
+     * searching among allClasses for classes nested directly in given jvmClass.
+     * The criterion is:
+     * <nested_class_signature> = 
+     * <jvmClassSignature> + '$' + <nested_class_name>
+     * but not
+     * <jvmClassSignature> + '$' + <nested_class_name> + '$' + ...
+     * since according to JDWP specificstion 
+     * "Types further nested within those types are not included",
+     * and not
+     * <jvmClassSignature> + '$' + <digit>
+     * since it is anonymous class and reference JDWP implementation
+     * doesn't return anonymous classes.
+     * But there is one nuance: given algorithm does not take into 
+     * account that class name of not-nested class can contain '$' symbol,
+     * that is not forbidden by the Java Language Specification.
+     * In this case such class with name containing '$' symbol may be returned 
+     * by ReferenceType.NestedTypes command too, although this class is not
+     * nested class.
+    */
+    const char nestedClassSign = '$';
+    jint nestedTypesCount = 0;
+    for (int allClassesIndex = 0; allClassesIndex < allClassesCount; allClassesIndex++) {
+        jclass klass = allClasses[allClassesIndex];
+        char* klassSignature = 0;
+
+        JVMTI_TRACE(err, jvmti->GetClassSignature(klass, &klassSignature, 0));
+
+        if (err != JVMTI_ERROR_NONE) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS
+            throw AgentException(err);
+        }
+        JvmtiAutoFree autoFreeKlassSignature(klassSignature);
+
+        size_t klassSignatureLength = strlen(klassSignature);
+        if ( jvmClassSignatureLength+2 > klassSignatureLength ) {
+            // <nested_class_signature> = 
+            // <jvmClassSignature> + '$' + <at_least_1_symbol> 
+            continue;
+        }
+
+        if ( strncmp(klassSignature, jvmClassSignature, jvmClassSignatureLength-1)
+                != 0 ) {
+            continue;
+        }
+        char* firstCharPtr = strchr(klassSignature, nestedClassSign);
+        if ( firstCharPtr == NULL ) {
+            // klass is not nested in jvmClass
+            continue;
+        }
+        char* lastCharPtr = strrchr(klassSignature, nestedClassSign);
+        if ( firstCharPtr != lastCharPtr ) {
+            // klass is nested in jvmClass but NOT directly
+            continue;
+        }
+        firstCharPtr++;
+        if ( isdigit(*firstCharPtr) ) {
+            // it is anonymous class  - ignore it
+            continue;
+        }
+        // klass is directly nested in jvmClass - it is desired nested class
+        allClasses[nestedTypesCount] = klass;
+        nestedTypesCount++;
+    }
+
+    // form reply data for all found out classes nested directly in given jvmClass
+    m_cmdParser->reply.WriteInt(nestedTypesCount);
+    JDWP_TRACE_DATA("NestedTypes: nestedTypes=" << nestedTypesCount);
+    for (int nestedClassesIndex = 0; nestedClassesIndex < nestedTypesCount; nestedClassesIndex++) {
+        jclass nestedClass = allClasses[nestedClassesIndex];
+
+        jdwpTypeTag refTypeTag = JDWP_TYPE_TAG_CLASS;
+        if (GetClassManager().IsInterfaceType(nestedClass) == JNI_TRUE ) {
+            // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+            refTypeTag = JDWP_TYPE_TAG_INTERFACE;
+        }
+        m_cmdParser->reply.WriteByte(refTypeTag);
+        m_cmdParser->reply.WriteReferenceTypeID(jni, nestedClass);
+        // can be: OutOfMemoryException, InternalErrorException,
+#ifndef NDEBUG
+        if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+            jvmtiError err;
+            char* signature = 0;
+            JVMTI_TRACE(err, jvmti->GetClassSignature(nestedClass, &signature, 0));
+            JvmtiAutoFree afcs(signature);
+            JDWP_TRACE_DATA("NestedTypes: send: nestedClass#" << nestedClassesIndex
+                << ", typeTag=" << refTypeTag
+                << ", nestedClassID=" << nestedClass
+                << ", signature=" << JDWP_CHECK_NULL(signature));
+        }
+#endif
+    }
+
+} // NestedTypesHandler::Execute()
+
+//------------------------------------------------------------------------------
+//StatusHandler(9)--------------------------------------------------------------
+
+void
+ReferenceType::StatusHandler::Execute(JNIEnv *jni) throw (AgentException)
+{
+    jint status;
+
+    jclass klass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(klass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("Status: received: refTypeID=" << klass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetClassStatus(klass, &status));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+
+    if (status == JVMTI_CLASS_STATUS_ARRAY) {
+       status = 0;
+    } else {
+        if ( status == JVMTI_CLASS_STATUS_PRIMITIVE ) {
+            status = 0;
+        }
+    }
+    m_cmdParser->reply.WriteInt(status);
+    JDWP_TRACE_DATA("Status: send: status=" << status);
+
+} // StatusHandler::Execute()
+
+//------------------------------------------------------------------------------
+//InterfacesHandler(10)---------------------------------------------------------
+
+void
+ReferenceType::InterfacesHandler::Execute(JNIEnv *jni)
+        throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("Interfaces: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+    jint interfacesCount = 0;
+    jclass* interfaces;
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetImplementedInterfaces(jvmClass,
+        &interfacesCount, &interfaces));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_CLASS_NOT_PREPARED, JVMTI_ERROR_INVALID_CLASS,
+        // JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeInterfaces(interfaces);
+
+    m_cmdParser->reply.WriteInt(interfacesCount);
+
+    JDWP_TRACE_DATA("Interfaces: interfaces=" << interfacesCount);
+    for (int i = 0; i < interfacesCount; i++) {
+        m_cmdParser->reply.WriteReferenceTypeID(jni, interfaces[i]);
+#ifndef NDEBUG
+        if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+            jvmtiError err;
+            char* signature = 0;
+            JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(interfaces[i], &signature, 0));
+            JvmtiAutoFree afcs(signature);
+            JDWP_TRACE_DATA("Interfaces: interface#" << i
+                << ", interfaceID=" << interfaces[i]
+                << ", classSignature=" << JDWP_CHECK_NULL(signature));
+        }
+#endif
+    }
+
+} // InterfacesHandler::Execute()
+
+//------------------------------------------------------------------------------
+//ClassObjectHandler(11)--------------------------------------------------------
+
+void
+ReferenceType::ClassObjectHandler::Execute(JNIEnv *jni)
+        throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("ClassObject: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature))
+    }
+#endif
+    m_cmdParser->reply.WriteObjectID(jni, jvmClass);
+    JDWP_TRACE_DATA("ClassObject: send: objectID=" << jvmClass);
+    
+
+} // ClassObjectHandler::Execute()
+
+//------------------------------------------------------------------------------
+//SourceDebugExtensionHandler(12)-----------------------------------------------
+
+void
+ReferenceType::SourceDebugExtensionHandler::Execute(JNIEnv *jni)
+        throw (AgentException)
+{
+    jclass jvmClass = m_cmdParser->command.ReadReferenceTypeID(jni);
+    // Can be: InternalErrorException, OutOfMemoryException,
+    // JDWP_ERROR_INVALID_CLASS, JDWP_ERROR_INVALID_OBJECT
+#ifndef NDEBUG
+    if (JDWP_TRACE_ENABLED(LOG_KIND_DATA)) {
+        jvmtiError err;
+        char* signature = 0;
+        JVMTI_TRACE(err, GetJvmtiEnv()->GetClassSignature(jvmClass, &signature, 0));
+        JvmtiAutoFree afcs(signature);
+        JDWP_TRACE_DATA("SourceDebugExtension: received: refTypeID=" << jvmClass
+            << ", classSignature=" << JDWP_CHECK_NULL(signature));
+    }
+#endif
+    char* sourceDebugExtension = 0;
+    jvmtiError err;
+    JVMTI_TRACE(err, GetJvmtiEnv()->GetSourceDebugExtension(jvmClass,
+        &sourceDebugExtension));
+
+    if (err != JVMTI_ERROR_NONE) {
+        // Can be: JVMTI_ERROR_MUST_POSSESS_CAPABILITY,JVMTI_ERROR_ABSENT_INFORMATION,
+        // JVMTI_ERROR_INVALID_CLASS, JVMTI_ERROR_NULL_POINTER
+        throw AgentException(err);
+    }
+    JvmtiAutoFree autoFreeDebugExtension(sourceDebugExtension);
+
+    m_cmdParser->reply.WriteString(sourceDebugExtension);
+    JDWP_TRACE_DATA("SourceDebugExtension: send: sourceDebugExtension=" 
+        << JDWP_CHECK_NULL(sourceDebugExtension));
+
+} // SourceDebugExtensionHandler::Execute()
+
+//------------------------------------------------------------------------------

Propchange: harmony/enhanced/jdktools/trunk/modules/jpda/src/common/other/jpda/jdwp/agent/commands/ReferenceType.cpp
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message