From c96e56fccc191a27409206b4f910fadb012e1586 Mon Sep 17 00:00:00 2001 From: Allan Gregersen Date: Fri, 1 Mar 2024 12:55:29 +0100 Subject: [PATCH] don't try to resolve method parameter types from debugger, parse the signature instead to calculate the correct argCount. --- .../truffle/espresso/jdwp/api/MethodRef.java | 14 +-- .../truffle/espresso/jdwp/impl/JDWP.java | 104 ++++++++++++------ .../oracle/truffle/espresso/impl/Method.java | 10 +- 3 files changed, 81 insertions(+), 47 deletions(-) diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java index 59d5df18eb1c..2f13fa9ea876 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/api/MethodRef.java @@ -107,13 +107,6 @@ public interface MethodRef { */ byte[] getOriginalCode(); - /** - * Returns all declared parameter types of the method. - * - * @return an array of parameter types - */ - KlassRef[] getParameters(); - /** * @return the local variable table of the method */ @@ -232,4 +225,11 @@ public interface MethodRef { * @return true if the method has a variable table */ boolean hasVariableTable(); + + /** + * Determines if the method was compiled with a variable type table. + * + * @return true if the method has a variable table + */ + boolean hasVariabletypeTable(); } diff --git a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java index a8031fb33060..1027d5ca8968 100644 --- a/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java +++ b/espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/JDWP.java @@ -28,6 +28,8 @@ import java.util.Collections; import java.util.List; import java.util.concurrent.Callable; +import java.util.stream.IntStream; +import java.util.stream.Stream; import com.oracle.truffle.api.interop.InteropException; import com.oracle.truffle.espresso.jdwp.api.CallFrame; @@ -1480,23 +1482,7 @@ static CommandResult createReply(Packet packet, JDWPContext context) { return new CommandResult(reply); } - if (!method.hasVariableTable()) { - reply.errorCode(ErrorCodes.ABSENT_INFORMATION); - return new CommandResult(reply); - } - - KlassRef[] params = method.getParameters(); - int argCnt = 0; // the number of words in the frame used by the arguments - for (KlassRef klass : params) { - if (klass.isPrimitive()) { - byte tag = klass.getTagConstant(); - if (tag == TagConstants.DOUBLE || tag == TagConstants.LONG) { - argCnt += 2; - } else { - argCnt++; - } - } - } + int argCnt = getArgCount(method.getSignatureAsString()); LocalRef[] locals = method.getLocalVariableTable().getLocals(); reply.writeInt(argCnt); @@ -1583,24 +1569,8 @@ static CommandResult createReply(Packet packet, JDWPContext context) { if (method == null) { return new CommandResult(reply); } - - if (!method.hasVariableTable()) { - reply.errorCode(ErrorCodes.ABSENT_INFORMATION); - return new CommandResult(reply); - } - - KlassRef[] params = method.getParameters(); - int argCnt = 0; // the number of words in the frame used by the arguments - for (KlassRef klass : params) { - if (klass.isPrimitive()) { - byte tag = klass.getTagConstant(); - if (tag == TagConstants.DOUBLE || tag == TagConstants.LONG) { - argCnt += 2; - } else { - argCnt++; - } - } - } + // the number of words in the frame used by the arguments + int argCnt = getArgCount(method.getSignatureAsString()); LocalRef[] locals = method.getLocalVariableTable().getLocals(); LocalRef[] genericLocals = method.getLocalVariableTypeTable().getLocals(); @@ -3240,6 +3210,70 @@ private static int checkSyntheticFlag(int modBits) { return mod; } + private static int getArgCount(String signature) { + int startIndex = signature.indexOf('(') + 1; + int endIndex = signature.indexOf(')'); + String parameterSig = signature.substring(startIndex, endIndex); + int currentCount = 0; + int currentIndex = 0; + char[] charArray = parameterSig.toCharArray(); + while (currentIndex < charArray.length) { + switch (charArray[currentIndex]) { + case 'D': + case 'J': { + currentCount += 2; + currentIndex++; + break; + } + case 'B': + case 'C': + case 'F': + case 'I': + case 'S': + case 'Z': { + currentCount++; + currentIndex++; + break; + } + case 'L': + currentCount++; + currentIndex = parameterSig.indexOf(';', currentIndex) + 1; + break; + case 'T': + throw new RuntimeException("unexpected type variable"); + case '[': + currentCount++; + currentIndex += parseArrayType(parameterSig, charArray, currentIndex + 1); + break; + default: + throw new RuntimeException("should not reach here"); + } + } + return currentCount; + } + + private static int parseArrayType(String signature, char[] charArray, int currentIndex) { + switch (charArray[currentIndex]) { + case 'D': + case 'J': + case 'B': + case 'C': + case 'F': + case 'I': + case 'S': + case 'Z': + return 2; + case 'L': + return 2 + signature.indexOf(';', currentIndex) - currentIndex; + case 'T': + throw new RuntimeException("unexpected type variable"); + case '[': + return 1 + parseArrayType(signature, charArray, currentIndex + 1); + default: + throw new RuntimeException("should not reach here"); + } + } + private static KlassRef verifyRefType(long refTypeId, PacketStream reply, JDWPContext context) { KlassRef klass; try { diff --git a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java index ad5c2980fd9b..9195bf48115b 100644 --- a/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java +++ b/espresso/src/com.oracle.truffle.espresso/src/com/oracle/truffle/espresso/impl/Method.java @@ -1418,11 +1418,6 @@ public byte[] getOriginalCode() { return getCodeAttribute().getOriginalCode(); } - @Override - public KlassRef[] getParameters() { - return getMethod().getParameters(); - } - @Override public LocalVariableTable getLocalVariableTable() { if (codeAttribute != null) { @@ -1444,6 +1439,11 @@ public boolean hasVariableTable() { return getLocalVariableTable() != LocalVariableTable.EMPTY_LVT; } + @Override + public boolean hasVariabletypeTable() { + return getLocalVariableTypeTable() != LocalVariableTable.EMPTY_LVTT; + } + @Override public LineNumberTableAttribute getLineNumberTable() { return getLineNumberTableAttribute();