You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@harmony.apache.org by ge...@apache.org on 2006/11/28 18:49:31 UTC
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/...
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