summaryrefslogtreecommitdiffstats
path: root/vm/jdwp
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2009-10-02 15:56:26 -0700
committerAndy McFadden <fadden@android.com>2009-10-13 11:23:49 -0700
commitf50c6d57afb09f8ed9da179a8bc8b409279ef8a6 (patch)
treedc8f331d30a7c4d7c600e390fe59cff182e6505a /vm/jdwp
parent9f6206a7758ab66de97d14b602fd329815eba380 (diff)
downloadandroid_dalvik-f50c6d57afb09f8ed9da179a8bc8b409279ef8a6.tar.gz
android_dalvik-f50c6d57afb09f8ed9da179a8bc8b409279ef8a6.tar.bz2
android_dalvik-f50c6d57afb09f8ed9da179a8bc8b409279ef8a6.zip
Add implementation of JDWP ClassType.NewInstance
Add a handler for the ClassType.NewInstance request, and some bits of plumbing to go with it. For bug 2157236.
Diffstat (limited to 'vm/jdwp')
-rw-r--r--vm/jdwp/JdwpHandler.c62
1 files changed, 52 insertions, 10 deletions
diff --git a/vm/jdwp/JdwpHandler.c b/vm/jdwp/JdwpHandler.c
index ff6ecf461..16d9a5d3a 100644
--- a/vm/jdwp/JdwpHandler.c
+++ b/vm/jdwp/JdwpHandler.c
@@ -110,10 +110,14 @@ static void jdwpWriteValue(ExpandBuf* pReply, int width, u8 value)
/*
* Common code for *_InvokeMethod requests.
+ *
+ * If "isConstructor" is set, this returns "objectId" rather than the
+ * expected-to-be-void return value of the called function.
*/
static JdwpError finishInvoke(JdwpState* state,
const u1* buf, int dataLen, ExpandBuf* pReply,
- ObjectId threadId, ObjectId objectId, RefTypeId classId, MethodId methodId)
+ ObjectId threadId, ObjectId objectId, RefTypeId classId, MethodId methodId,
+ bool isConstructor)
{
JdwpError err = ERR_NONE;
u8* argArray = NULL;
@@ -121,6 +125,8 @@ static JdwpError finishInvoke(JdwpState* state,
u4 options; /* enum InvokeOptions bit flags */
int i;
+ assert(!isConstructor || objectId != 0);
+
numArgs = read4BE(&buf);
LOGV(" --> threadId=%llx objectId=%llx\n", threadId, objectId);
@@ -163,11 +169,16 @@ static JdwpError finishInvoke(JdwpState* state,
goto bail;
if (err == ERR_NONE) {
- int width = dvmDbgGetTagWidth(resultTag);
-
- expandBufAdd1(pReply, resultTag);
- if (width != 0)
- jdwpWriteValue(pReply, width, resultValue);
+ if (isConstructor) {
+ expandBufAdd1(pReply, JT_OBJECT);
+ expandBufAddObjectId(pReply, objectId);
+ } else {
+ int width = dvmDbgGetTagWidth(resultTag);
+
+ expandBufAdd1(pReply, resultTag);
+ if (width != 0)
+ jdwpWriteValue(pReply, width, resultValue);
+ }
expandBufAdd1(pReply, JT_OBJECT);
expandBufAddObjectId(pReply, exceptObjId);
@@ -400,8 +411,10 @@ static JdwpError handleVM_CreateString(JdwpState* state,
LOGV(" Req to create string '%s'\n", str);
stringId = dvmDbgCreateString(str);
- expandBufAddObjectId(pReply, stringId);
+ if (stringId == 0)
+ return ERR_OUT_OF_MEMORY;
+ expandBufAddObjectId(pReply, stringId);
return ERR_NONE;
}
@@ -834,7 +847,36 @@ static JdwpError handleCT_InvokeMethod(JdwpState* state,
methodId = dvmReadMethodId(&buf);
return finishInvoke(state, buf, dataLen, pReply,
- threadId, 0, classId, methodId);
+ threadId, 0, classId, methodId, false);
+}
+
+/*
+ * Create a new object of the requested type, and invoke the specified
+ * constructor.
+ *
+ * Example: in IntelliJ, create a watch on "new String(myByteArray)" to
+ * see the contents of a byte[] as a string.
+ */
+static JdwpError handleCT_NewInstance(JdwpState* state,
+ const u1* buf, int dataLen, ExpandBuf* pReply)
+{
+ RefTypeId classId;
+ ObjectId threadId;
+ MethodId methodId;
+ ObjectId objectId;
+ u4 numArgs;
+
+ classId = dvmReadRefTypeId(&buf);
+ threadId = dvmReadObjectId(&buf);
+ methodId = dvmReadMethodId(&buf);
+
+ LOGV("Creating instance of %s\n", dvmDbgGetClassDescriptor(classId));
+ objectId = dvmDbgCreateObject(classId);
+ if (objectId == 0)
+ return ERR_OUT_OF_MEMORY;
+
+ return finishInvoke(state, buf, dataLen, pReply,
+ threadId, objectId, classId, methodId, true);
}
/*
@@ -1011,7 +1053,7 @@ static JdwpError handleOR_InvokeMethod(JdwpState* state,
methodId = dvmReadMethodId(&buf);
return finishInvoke(state, buf, dataLen, pReply,
- threadId, objectId, classId, methodId);
+ threadId, objectId, classId, methodId, false);
}
/*
@@ -1955,7 +1997,7 @@ static const JdwpHandlerMap gHandlerMap[] = {
{ 3, 1, handleCT_Superclass, "ClassType.Superclass" },
{ 3, 2, handleCT_SetValues, "ClassType.SetValues" },
{ 3, 3, handleCT_InvokeMethod, "ClassType.InvokeMethod" },
- //3, 4, NewInstance
+ { 3, 4, handleCT_NewInstance, "ClassType.NewInstance" },
/* ArrayType command set (4) */
//4, 1, NewInstance