aboutsummaryrefslogtreecommitdiff
path: root/libjava/gnu/classpath/jdwp/natVMMethod.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libjava/gnu/classpath/jdwp/natVMMethod.cc')
-rw-r--r--libjava/gnu/classpath/jdwp/natVMMethod.cc134
1 files changed, 121 insertions, 13 deletions
diff --git a/libjava/gnu/classpath/jdwp/natVMMethod.cc b/libjava/gnu/classpath/jdwp/natVMMethod.cc
index 7dea4747731..1cea54dae9d 100644
--- a/libjava/gnu/classpath/jdwp/natVMMethod.cc
+++ b/libjava/gnu/classpath/jdwp/natVMMethod.cc
@@ -1,6 +1,6 @@
// natVMMethod.cc -- native support for VMMethod
-/* Copyright (C) 2006 Free Software Foundation
+/* Copyright (C) 2006, 2007 Free Software Foundation
This file is part of libgcj.
@@ -11,39 +11,74 @@ details. */
#include <config.h>
#include <gcj/cni.h>
#include <java-interp.h>
+#include <jvmti.h>
+#include "jvmti-int.h"
+#include <java/lang/reflect/Modifier.h>
#include <gnu/classpath/jdwp/VMMethod.h>
+#include <gnu/classpath/jdwp/exception/AbsentInformationException.h>
+#include <gnu/classpath/jdwp/exception/InvalidMethodException.h>
#include <gnu/classpath/jdwp/exception/JdwpInternalErrorException.h>
#include <gnu/classpath/jdwp/util/LineTable.h>
#include <gnu/classpath/jdwp/util/VariableTable.h>
-java::lang::String*
+using namespace java::lang;
+
+#define CHECK_INTERP_CLASS() \
+do \
+ { \
+ if (!_Jv_IsInterpretedClass (getDeclaringClass ())) \
+ { \
+ ::java::lang::String *msg = JvNewStringLatin1 ("native class"); \
+ throw new exception::JdwpInternalErrorException (msg); \
+ } \
+ } \
+while (0)
+
+jstring
gnu::classpath::jdwp::VMMethod::getName ()
{
- return NULL;
+ jvmtiEnv *env = _Jv_GetJDWP_JVMTIEnv ();
+ jmethodID method = reinterpret_cast<jmethodID> (_methodId);
+ char *name;
+ env->GetMethodName (method, &name, NULL, NULL);
+ jstring string = JvNewStringUTF (name);
+ env->Deallocate (reinterpret_cast<unsigned char *> (name));
+ return string;
}
-java::lang::String*
+jstring
gnu::classpath::jdwp::VMMethod::getSignature ()
{
- return NULL;
+ jvmtiEnv *env = _Jv_GetJDWP_JVMTIEnv ();
+ jmethodID method = reinterpret_cast<jmethodID> (_methodId);
+ char *signature;
+ env->GetMethodName (method, NULL, &signature, NULL);
+ jstring string = JvNewStringUTF (signature);
+ env->Deallocate (reinterpret_cast<unsigned char *> (signature));
+ return string;
}
jint
gnu::classpath::jdwp::VMMethod::getModifiers ()
{
- return 0;
+ jvmtiEnv *env = _Jv_GetJDWP_JVMTIEnv ();
+ jmethodID method = reinterpret_cast<jmethodID> (_methodId);
+ jint flags;
+ env->GetMethodModifiers (method, &flags);
+
+ // If this class is compiled, as far as JDWP is concerned, its methods are
+ // native. This will set the native flag for these methods.
+ if (!_Jv_IsInterpretedClass (getDeclaringClass ()))
+ flags |= ::java::lang::reflect::Modifier::NATIVE;
+
+ return flags;
}
gnu::classpath::jdwp::util::LineTable *
gnu::classpath::jdwp::VMMethod::getLineTable ()
{
- if (!_Jv_IsInterpretedClass (getDeclaringClass ()))
- {
- // this should not happen
- ::java::lang::String *msg = JvNewStringLatin1 ("native class");
- throw new exception::JdwpInternalErrorException (msg);
- }
+ CHECK_INTERP_CLASS ();
jmethodID desired_method = reinterpret_cast<jmethodID> (_methodId);
@@ -79,5 +114,78 @@ gnu::classpath::jdwp::VMMethod::getLineTable ()
gnu::classpath::jdwp::util::VariableTable*
gnu::classpath::jdwp::VMMethod::getVariableTable ()
{
- return NULL;
+ using namespace gnu::classpath::jdwp::util;
+
+ jvmtiEnv *env = _Jv_GetJDWP_JVMTIEnv ();
+
+ CHECK_INTERP_CLASS ();
+
+ jmethodID meth = reinterpret_cast<jmethodID> (_methodId);
+ jvmtiLocalVariableEntry *var_table;
+ jint num_slots, args_len;
+
+ jvmtiError jerr = env->GetLocalVariableTable (meth, &num_slots, &var_table);
+
+ if (jerr != JVMTI_ERROR_NONE)
+ goto error;
+
+ jerr = env->GetArgumentsSize (meth, &args_len);
+
+ if (jerr != JVMTI_ERROR_NONE)
+ {
+ error:
+ using namespace gnu::classpath::jdwp::exception;
+ char *error;
+ env->GetErrorName (jerr, &error);
+ String *msg = JvNewStringUTF (error);
+ env->Deallocate (reinterpret_cast<unsigned char *> (error));
+
+ if (jerr == JVMTI_ERROR_NATIVE_METHOD)
+ throw new AbsentInformationException (msg);
+ else if (jerr == JVMTI_ERROR_INVALID_METHODID)
+ throw new InvalidMethodException (_methodId);
+ else
+ throw new JdwpInternalErrorException (msg);
+ }
+
+ jlongArray start_pcs = JvNewLongArray (num_slots);
+ jlong *start_pcs_ptr = elements (start_pcs);
+ jintArray lengths = JvNewIntArray (num_slots);
+ jint *lengths_ptr = elements (lengths);
+ jintArray slots = JvNewIntArray (num_slots);
+ jint *slots_ptr = elements (slots);
+ JArray<String *> *names = reinterpret_cast<JArray<String *> *>
+ (JvNewObjectArray (num_slots,
+ &String::class$, NULL));
+ jstring *names_ptr = elements (names);
+ JArray<String *> *signatures = reinterpret_cast<JArray<String *> *>
+ (JvNewObjectArray (num_slots,
+ &String::class$, NULL));
+ jstring *signatures_ptr = elements (signatures);
+
+ // Get the information out of the JVMTI strucutre and Deallocate the strings.
+ for (int i = 0; i < num_slots; i++)
+ {
+ start_pcs_ptr[i] = var_table[i].start_location;
+ lengths_ptr[i] = var_table[i].length;
+ slots_ptr[i] = var_table[i].slot;
+ names_ptr[i] = JvNewStringUTF (var_table[i].name);
+ env->Deallocate (reinterpret_cast<unsigned char *>
+ (var_table[i].name));
+ signatures_ptr[i] = JvNewStringUTF (var_table[i].signature);
+ env->Deallocate (reinterpret_cast<unsigned char *>
+ (var_table[i].signature));
+ env->Deallocate (reinterpret_cast<unsigned char *>
+ (var_table[i].generic_signature));
+ }
+
+ // Now Deallocate the table since it's strings have already been freed.
+ env->Deallocate (reinterpret_cast<unsigned char *> (var_table));
+
+ // Create the new JDWP VariableTable to return with the now filled arrays.
+ VariableTable* jdwp_vtable = new VariableTable (args_len, num_slots,
+ start_pcs, names, signatures,
+ lengths, slots);
+
+ return jdwp_vtable;
}