Skip to content

Commit 4adb1ee

Browse files
committed
[GR-52240] Fix NPE in JDWP when debugger asks for local variable table.
PullRequest: graal/17158
2 parents 9ad3fd6 + 8e3d468 commit 4adb1ee

File tree

3 files changed

+67
-59
lines changed
  • espresso/src
    • com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl
    • com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp

3 files changed

+67
-59
lines changed

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,6 @@ public interface MethodRef {
107107
*/
108108
byte[] getOriginalCode();
109109

110-
/**
111-
* Returns all declared parameter types of the method.
112-
*
113-
* @return an array of parameter types
114-
*/
115-
KlassRef[] getParameters();
116-
117110
/**
118111
* @return the local variable table of the method
119112
*/
@@ -225,11 +218,4 @@ public interface MethodRef {
225218
* @return last bci
226219
*/
227220
long getLastBCI();
228-
229-
/**
230-
* Determines if the method was compiled with a variable table.
231-
*
232-
* @return true if the method has a variable table
233-
*/
234-
boolean hasVariableTable();
235221
}

espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java

Lines changed: 67 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1480,23 +1480,7 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
14801480
return new CommandResult(reply);
14811481
}
14821482

1483-
if (!method.hasVariableTable()) {
1484-
reply.errorCode(ErrorCodes.ABSENT_INFORMATION);
1485-
return new CommandResult(reply);
1486-
}
1487-
1488-
KlassRef[] params = method.getParameters();
1489-
int argCnt = 0; // the number of words in the frame used by the arguments
1490-
for (KlassRef klass : params) {
1491-
if (klass.isPrimitive()) {
1492-
byte tag = klass.getTagConstant();
1493-
if (tag == TagConstants.DOUBLE || tag == TagConstants.LONG) {
1494-
argCnt += 2;
1495-
} else {
1496-
argCnt++;
1497-
}
1498-
}
1499-
}
1483+
int argCnt = getArgCount(method.getSignatureAsString());
15001484
LocalRef[] locals = method.getLocalVariableTable().getLocals();
15011485

15021486
reply.writeInt(argCnt);
@@ -1583,24 +1567,8 @@ static CommandResult createReply(Packet packet, JDWPContext context) {
15831567
if (method == null) {
15841568
return new CommandResult(reply);
15851569
}
1586-
1587-
if (!method.hasVariableTable()) {
1588-
reply.errorCode(ErrorCodes.ABSENT_INFORMATION);
1589-
return new CommandResult(reply);
1590-
}
1591-
1592-
KlassRef[] params = method.getParameters();
1593-
int argCnt = 0; // the number of words in the frame used by the arguments
1594-
for (KlassRef klass : params) {
1595-
if (klass.isPrimitive()) {
1596-
byte tag = klass.getTagConstant();
1597-
if (tag == TagConstants.DOUBLE || tag == TagConstants.LONG) {
1598-
argCnt += 2;
1599-
} else {
1600-
argCnt++;
1601-
}
1602-
}
1603-
}
1570+
// the number of words in the frame used by the arguments
1571+
int argCnt = getArgCount(method.getSignatureAsString());
16041572
LocalRef[] locals = method.getLocalVariableTable().getLocals();
16051573
LocalRef[] genericLocals = method.getLocalVariableTypeTable().getLocals();
16061574

@@ -3240,6 +3208,70 @@ private static int checkSyntheticFlag(int modBits) {
32403208
return mod;
32413209
}
32423210

3211+
private static int getArgCount(String signature) {
3212+
int startIndex = signature.indexOf('(') + 1;
3213+
int endIndex = signature.indexOf(')');
3214+
String parameterSig = signature.substring(startIndex, endIndex);
3215+
int currentCount = 0;
3216+
int currentIndex = 0;
3217+
char[] charArray = parameterSig.toCharArray();
3218+
while (currentIndex < charArray.length) {
3219+
switch (charArray[currentIndex]) {
3220+
case 'D':
3221+
case 'J': {
3222+
currentCount += 2;
3223+
currentIndex++;
3224+
break;
3225+
}
3226+
case 'B':
3227+
case 'C':
3228+
case 'F':
3229+
case 'I':
3230+
case 'S':
3231+
case 'Z': {
3232+
currentCount++;
3233+
currentIndex++;
3234+
break;
3235+
}
3236+
case 'L':
3237+
currentCount++;
3238+
currentIndex = parameterSig.indexOf(';', currentIndex) + 1;
3239+
break;
3240+
case 'T':
3241+
throw new RuntimeException("unexpected type variable");
3242+
case '[':
3243+
currentCount++;
3244+
currentIndex += parseArrayType(parameterSig, charArray, currentIndex + 1);
3245+
break;
3246+
default:
3247+
throw new RuntimeException("should not reach here");
3248+
}
3249+
}
3250+
return currentCount;
3251+
}
3252+
3253+
private static int parseArrayType(String signature, char[] charArray, int currentIndex) {
3254+
switch (charArray[currentIndex]) {
3255+
case 'D':
3256+
case 'J':
3257+
case 'B':
3258+
case 'C':
3259+
case 'F':
3260+
case 'I':
3261+
case 'S':
3262+
case 'Z':
3263+
return 2;
3264+
case 'L':
3265+
return 2 + signature.indexOf(';', currentIndex) - currentIndex;
3266+
case 'T':
3267+
throw new RuntimeException("unexpected type variable");
3268+
case '[':
3269+
return 1 + parseArrayType(signature, charArray, currentIndex + 1);
3270+
default:
3271+
throw new RuntimeException("should not reach here");
3272+
}
3273+
}
3274+
32433275
private static KlassRef verifyRefType(long refTypeId, PacketStream reply, JDWPContext context) {
32443276
KlassRef klass;
32453277
try {

espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,11 +1418,6 @@ public byte[] getOriginalCode() {
14181418
return getCodeAttribute().getOriginalCode();
14191419
}
14201420

1421-
@Override
1422-
public KlassRef[] getParameters() {
1423-
return getMethod().getParameters();
1424-
}
1425-
14261421
@Override
14271422
public LocalVariableTable getLocalVariableTable() {
14281423
if (codeAttribute != null) {
@@ -1439,11 +1434,6 @@ public LocalVariableTable getLocalVariableTypeTable() {
14391434
return LocalVariableTable.EMPTY_LVTT;
14401435
}
14411436

1442-
@Override
1443-
public boolean hasVariableTable() {
1444-
return getLocalVariableTable() != LocalVariableTable.EMPTY_LVT;
1445-
}
1446-
14471437
@Override
14481438
public LineNumberTableAttribute getLineNumberTable() {
14491439
return getLineNumberTableAttribute();

0 commit comments

Comments
 (0)