use of com.oracle.truffle.espresso.descriptors.ByteSequence in project graal by oracle.
the class ConstantPoolPatcher method patchConstantPool.
public static byte[] patchConstantPool(byte[] bytes, Map<Symbol<Symbol.Name>, Symbol<Symbol.Name>> rules, EspressoContext context) throws ClassFormatError {
byte[] result = Arrays.copyOf(bytes, bytes.length);
ClassfileStream stream = new ClassfileStream(bytes, null);
// skip magic and version - 8 bytes
stream.skip(8);
final int length = stream.readU2();
int byteArrayGrowth = 0;
int i = 1;
while (i < length) {
final int tagByte = stream.readU1();
final ConstantPool.Tag tag = ConstantPool.Tag.fromValue(tagByte);
switch(tag) {
case UTF8:
// utfLength is first two bytes
int position = stream.getPosition() + 2;
ByteSequence byteSequence = stream.readByteSequenceUTF();
Symbol<Symbol.Name> asSymbol = context.getNames().getOrCreate(byteSequence);
if (rules.containsKey(asSymbol)) {
int originalLegth = byteSequence.length();
Symbol<Symbol.Name> replacedSymbol = rules.get(asSymbol);
if (originalLegth == replacedSymbol.length()) {
replacedSymbol.writeTo(result, position + byteArrayGrowth);
} else {
int diff = replacedSymbol.length() - originalLegth;
byteArrayGrowth += diff;
// make room for the longer class name
result = Arrays.copyOf(result, result.length + diff);
int currentPosition = stream.getPosition();
// shift the tail of array
System.arraycopy(bytes, currentPosition, result, currentPosition + byteArrayGrowth, bytes.length - currentPosition);
// update utfLength
char utfLength = (char) replacedSymbol.length();
int utfLengthPosition = position - 2 + byteArrayGrowth - diff;
result[utfLengthPosition] = (byte) (utfLength >> 8);
result[utfLengthPosition + 1] = (byte) (utfLength);
// insert patched byte array
replacedSymbol.writeTo(result, utfLengthPosition + 2);
}
}
break;
case CLASS:
case STRING:
case METHODTYPE:
stream.readU2();
break;
case FIELD_REF:
case METHOD_REF:
case INTERFACE_METHOD_REF:
case NAME_AND_TYPE:
case DYNAMIC:
case INVOKEDYNAMIC:
stream.readU2();
stream.readU2();
break;
case INTEGER:
stream.readS4();
break;
case FLOAT:
stream.readFloat();
break;
case LONG:
stream.readS8();
++i;
break;
case DOUBLE:
stream.readDouble();
++i;
break;
case METHODHANDLE:
stream.readU1();
stream.readU2();
break;
default:
throw new ClassFormatError();
}
i++;
}
return result;
}
use of com.oracle.truffle.espresso.descriptors.ByteSequence in project graal by oracle.
the class ConstantPoolPatcher method getDirectInnerClassNames.
public static void getDirectInnerClassNames(Symbol<Symbol.Name> fileSystemName, byte[] bytes, ArrayList<Symbol<Symbol.Name>> innerNames, EspressoContext context) throws ClassFormatError {
ClassfileStream stream = new ClassfileStream(bytes, null);
ByteSequence fileNameBytes = fileSystemName.subSequence(0, fileSystemName.length());
// skip magic and version - 8 bytes
stream.skip(8);
final int length = stream.readU2();
int i = 1;
while (i < length) {
final int tagByte = stream.readU1();
final ConstantPool.Tag tag = ConstantPool.Tag.fromValue(tagByte);
switch(tag) {
case UTF8:
ByteSequence byteSequence = stream.readByteSequenceUTF();
if (byteSequence.contentStartsWith(fileNameBytes) && !byteSequence.contentEquals(fileNameBytes)) {
if (InnerClassRedefiner.ANON_INNER_CLASS_PATTERN.matcher(byteSequence.toString()).matches()) {
innerNames.add(context.getNames().getOrCreate(byteSequence));
}
}
break;
case CLASS:
case STRING:
case METHODTYPE:
stream.readU2();
break;
case FIELD_REF:
case METHOD_REF:
case INTERFACE_METHOD_REF:
case NAME_AND_TYPE:
case DYNAMIC:
case INVOKEDYNAMIC:
stream.readU2();
stream.readU2();
break;
case INTEGER:
stream.readS4();
break;
case FLOAT:
stream.readFloat();
break;
case LONG:
stream.readS8();
++i;
break;
case DOUBLE:
stream.readDouble();
++i;
break;
case METHODHANDLE:
stream.readU1();
stream.readU2();
break;
default:
throw new ClassFormatError();
}
i++;
}
}
Aggregations