Commit 948607b2 authored by forax's avatar forax
Browse files

prototype of 'Q' qualifier support

parent 7892659d
......@@ -2005,7 +2005,7 @@ public class ClassReader {
while (desc.charAt(i) == '[') {
++i;
}
if (desc.charAt(i) == 'L') {
if (desc.charAt(i) == 'L' || desc.charAt(i) == 'Q') { // value type support
++i;
while (desc.charAt(i) != ';') {
++i;
......@@ -2014,6 +2014,7 @@ public class ClassReader {
locals[local++] = desc.substring(j, ++i);
break;
case 'L':
case 'Q': // value type support
while (desc.charAt(i) != ';') {
++i;
}
......
......@@ -70,7 +70,7 @@ final class Frame {
* stack types. VALUE depends on KIND. For LOCAL types, it is an index in
* the input local variable types. For STACK types, it is a position
* relatively to the top of input frame stack. For BASE types, it is either
* one of the constants defined below, or for OBJECT and UNINITIALIZED
* one of the constants defined below, or for OBJECT, VALUE and UNINITIALIZED
* types, a tag and an index in the type table.
*
* Output frames can contain types of any kind and with a positive or
......@@ -155,6 +155,8 @@ final class Frame {
* instruction offset and an internal class name).
*/
static final int UNINITIALIZED = BASE | 0x800000;
/**
* Kind of the types that are relative to the local variable types of an
......@@ -640,6 +642,7 @@ final class Frame {
case 'D':
return DOUBLE;
case 'L':
case 'Q': // FIXME revisit value type support
// stores the internal name, not the descriptor!
t = desc.substring(index + 1, desc.length() - 1);
return OBJECT | cw.addType(t);
......@@ -677,6 +680,7 @@ final class Frame {
data = DOUBLE;
break;
// case 'L':
// case 'Q': //FXIME revisit to support value type
default:
// stores the internal name, not the descriptor
t = desc.substring(dims + 1, desc.length() - 1);
......
......@@ -1787,7 +1787,7 @@ class MethodWriter extends MethodVisitor {
while (descriptor.charAt(i) == '[') {
++i;
}
if (descriptor.charAt(i) == 'L') {
if (descriptor.charAt(i) == 'L' || descriptor.charAt(i) == 'Q') { // support value type
++i;
while (descriptor.charAt(i) != ';') {
++i;
......@@ -1797,6 +1797,7 @@ class MethodWriter extends MethodVisitor {
| cw.addType(descriptor.substring(j, ++i));
break;
case 'L':
case 'Q': // support value type
while (descriptor.charAt(i) != ';') {
++i;
}
......@@ -1972,7 +1973,7 @@ class MethodWriter extends MethodVisitor {
sb.append('[');
}
if ((t & Frame.BASE_KIND) == Frame.OBJECT) {
sb.append('L');
sb.append('L'); //FIXME bug !, we should either store the kind (L or Q) or have two type FRAME.OBJECT, FRAME.STRUCT
sb.append(cw.typeTable[t & Frame.BASE_VALUE].strVal1);
sb.append(';');
} else {
......
......@@ -95,11 +95,16 @@ public class Type {
* The sort of object reference types. See {@link #getSort getSort}.
*/
public static final int OBJECT = 10;
/**
* The sort of method types. See {@link #getSort getSort}.
*/
public static final int METHOD = 11;
/**
* The sort of value types. See {@link #getSort getSort}.
*/
public static final int VALUE = 12;
/**
* The <tt>void</tt> type.
......@@ -226,7 +231,7 @@ public class Type {
*/
public static Type getObjectType(final String internalName) {
char[] buf = internalName.toCharArray();
return new Type(buf[0] == '[' ? ARRAY : OBJECT, buf, 0, buf.length);
return new Type(buf[0] == '[' ? ARRAY : buf[0] == 'L' ? OBJECT: VALUE, buf, 0, buf.length); // support value type
}
/**
......@@ -329,7 +334,7 @@ public class Type {
char car = buf[off++];
if (car == ')') {
break;
} else if (car == 'L') {
} else if (car == 'L' || car == 'Q') { // support value type
while (buf[off++] != ';') {
}
++size;
......@@ -342,7 +347,7 @@ public class Type {
size = 0;
while (buf[off] != ')') {
args[size] = getType(buf, off);
off += args[size].len + (args[size].sort == OBJECT ? 2 : 0);
off += args[size].len + ((args[size].sort == OBJECT || args[size].sort == VALUE) ? 2 : 0); // support value type
size += 1;
}
return args;
......@@ -413,7 +418,7 @@ public class Type {
car = desc.charAt(c);
return n << 2
| (car == 'V' ? 0 : (car == 'D' || car == 'J' ? 2 : 1));
} else if (car == 'L') {
} else if (car == 'L' || car == 'Q') { // support value type
while (desc.charAt(c++) != ';') {
}
n += 1;
......@@ -477,11 +482,12 @@ public class Type {
}
return new Type(ARRAY, buf, off, len + 1);
case 'L':
case 'Q':
len = 1;
while (buf[off + len] != ';') {
++len;
}
return new Type(OBJECT, buf, off + 1, len - 1);
return new Type(buf[off] == 'L'? OBJECT: VALUE, buf, off + 1, len - 1); // support value type
// case '(':
default:
return new Type(METHOD, buf, off, buf.length - off);
......@@ -498,8 +504,8 @@ public class Type {
* @return {@link #VOID VOID}, {@link #BOOLEAN BOOLEAN}, {@link #CHAR CHAR},
* {@link #BYTE BYTE}, {@link #SHORT SHORT}, {@link #INT INT},
* {@link #FLOAT FLOAT}, {@link #LONG LONG}, {@link #DOUBLE DOUBLE},
* {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT} or {@link #METHOD
* METHOD}.
* {@link #ARRAY ARRAY}, {@link #OBJECT OBJECT}, {@link #VALUE VALUE}
* or {@link #METHOD METHOD}.
*/
public int getSort() {
return sort;
......@@ -562,6 +568,7 @@ public class Type {
}
return sb.toString();
case OBJECT:
case VALUE: // support value type
return new String(buf, off, len).replace('/', '.');
default:
return null;
......@@ -665,8 +672,8 @@ public class Type {
// descriptor is in byte 3 of 'off' for primitive types (buf ==
// null)
buf.append((char) ((off & 0xFF000000) >>> 24));
} else if (sort == OBJECT) {
buf.append('L');
} else if (sort == OBJECT || sort == VALUE) {
buf.append((sort == OBJECT)? 'L': 'Q'); // support value type
buf.append(this.buf, off, len);
buf.append(';');
} else { // sort == ARRAY || sort == METHOD
......@@ -779,7 +786,8 @@ public class Type {
buf.append('[');
d = d.getComponentType();
} else {
buf.append('L');
//FIXME add support for value type, something like c.isValueType ?
buf.append('L');
String name = d.getName();
int len = name.length();
for (int i = 0; i < len; ++i) {
......
......@@ -539,6 +539,7 @@ public class AnalyzerAdapter extends MethodVisitor {
}
break;
// case 'L':
// case 'Q' // value type support
default:
if (index == 0) {
push(desc.substring(1, desc.length() - 1));
......
......@@ -166,7 +166,7 @@ public class Method {
* @throws IllegalArgumentException
* if <code>method</code> could not get parsed.
*/
public static Method getMethod(final String method,
public static Method getMethod(final String method, //FIXME doesn't support value type
final boolean defaultPackage) throws IllegalArgumentException {
int space = method.indexOf(' ');
int start = method.indexOf('(', space) + 1;
......
......@@ -60,9 +60,10 @@ public abstract class Remapper {
}
return s;
case Type.OBJECT:
case Type.VALUE:
String newType = map(t.getInternalName());
if (newType != null) {
return 'L' + newType + ';';
return ((t.getSort() == Type.OBJECT)?'L' : 'Q') + newType + ';';
}
}
return desc;
......@@ -77,6 +78,7 @@ public abstract class Remapper {
}
return Type.getType(s);
case Type.OBJECT:
case Type.VALUE:
s = map(t.getInternalName());
return s != null ? Type.getObjectType(s) : t;
case Type.METHOD:
......
......@@ -65,6 +65,11 @@ public class RemappingSignatureAdapter extends SignatureVisitor {
className = name;
v.visitClassType(remapper.mapType(name));
}
@Override
public void visitValueType(String name) {
throw new UnsupportedOperationException("value type not supported"); // support for value type
}
@Override
public void visitInnerClassType(String name) {
......
......@@ -64,6 +64,12 @@ public class SignatureRemapper extends SignatureVisitor {
classNames.push(name);
v.visitClassType(remapper.mapType(name));
}
@Override
public void visitValueType(String name) {
classNames.push(name);
v.visitValueType(remapper.mapType(name));
}
@Override
public void visitInnerClassType(String name) {
......
......@@ -83,7 +83,7 @@ public class SignatureReader {
pos = end + 1;
c = signature.charAt(pos);
if (c == 'L' || c == '[' || c == 'T') {
if (c == 'L' || c == 'Q' || c == '[' || c == 'T') { // support for value type
pos = parseType(signature, pos, v.visitClassBound());
}
......@@ -169,7 +169,7 @@ public class SignatureReader {
v.visitTypeVariable(signature.substring(pos, end));
return end + 1;
default: // case 'L':
default: // case 'L': or case 'Q':
start = pos;
visited = false;
inner = false;
......@@ -182,7 +182,11 @@ public class SignatureReader {
if (inner) {
v.visitInnerClassType(name);
} else {
v.visitClassType(name);
if (c == 'L') {
v.visitClassType(name);
} else {
v.visitValueType(name); // support value type
}
}
}
if (c == ';') {
......
......@@ -202,7 +202,16 @@ public abstract class SignatureVisitor {
*/
public void visitClassType(String name) {
}
/**
* Starts the visit of a signature corresponding to a value type.
*
* @param name
* the internal name of the value type.
*/
public void visitValueType(String name) {
}
/**
* Visits an inner class.
*
......
......@@ -155,6 +155,13 @@ public class SignatureWriter extends SignatureVisitor {
buf.append(name);
argumentStack *= 2;
}
@Override
public void visitValueType(final String name) {
buf.append('Q');
buf.append(name);
argumentStack *= 2;
}
@Override
public void visitInnerClassType(final String name) {
......
......@@ -630,7 +630,7 @@ public class CheckClassAdapter extends ClassVisitor {
pos = checkFormalTypeParameters(signature, pos);
}
pos = checkClassTypeSignature(signature, pos);
while (getChar(signature, pos) == 'L') {
while (getChar(signature, pos) == 'L') { // FIXME revisit for value type
pos = checkClassTypeSignature(signature, pos);
}
if (pos != signature.length()) {
......@@ -666,7 +666,7 @@ public class CheckClassAdapter extends ClassVisitor {
}
while (getChar(signature, pos) == '^') {
++pos;
if (getChar(signature, pos) == 'L') {
if (getChar(signature, pos) == 'L') { //FIXME revisit for value type
pos = checkClassTypeSignature(signature, pos);
} else {
pos = checkTypeVariableSignature(signature, pos);
......@@ -826,6 +826,7 @@ public class CheckClassAdapter extends ClassVisitor {
switch (getChar(signature, pos)) {
case 'L':
case 'Q': // support value type
return checkClassTypeSignature(signature, pos);
case '[':
return checkTypeSignature(signature, pos + 1);
......@@ -848,7 +849,7 @@ public class CheckClassAdapter extends ClassVisitor {
// L Identifier ( / Identifier )* TypeArguments? ( . Identifier
// TypeArguments? )* ;
pos = checkChar('L', signature, pos);
pos = checkChar('L', signature, pos); //FIXME revisit for value type support
pos = checkIdentifier(signature, pos);
while (getChar(signature, pos) == '/') {
pos = checkIdentifier(signature, pos + 1);
......
......@@ -1421,6 +1421,7 @@ public class CheckMethodAdapter extends MethodVisitor {
+ desc);
}
case 'L':
case 'Q': // value type support
index = desc.indexOf(';', start);
if (index == -1 || index - start < 2) {
throw new IllegalArgumentException("Invalid descriptor: "
......
......@@ -283,6 +283,18 @@ public class CheckSignatureAdapter extends SignatureVisitor {
sv.visitClassType(name);
}
}
@Override
public void visitValueType(final String name) { // support value type
if (type != TYPE_SIGNATURE || state != EMPTY) {
throw new IllegalStateException();
}
CheckMethodAdapter.checkInternalName(name, "value class name");
state = CLASS_TYPE; //FIXME revisit
if (sv != null) {
sv.visitValueType(name);
}
}
@Override
public void visitInnerClassType(final String name) {
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment