renamed constantpool entries again. fixed some issues. ConstantPool output seems to get there

This commit is contained in:
Sander Hautvast 2020-11-09 14:32:05 +01:00
parent c6db240f47
commit 50649ea1a8
31 changed files with 296 additions and 242 deletions

View file

@ -24,16 +24,35 @@ public class Compiler {
private byte[] doCompile() { private byte[] doCompile() {
ByteBuf buf = new ByteBuf(); ByteBuf buf = new ByteBuf();
buf.add(0xCA, 0xFE, 0xBA, 0xBE); buf.addU8(0xCA, 0xFE, 0xBA, 0xBE);
buf.add(beeClass.getClassFileVersion().getMinor()); buf.addU16(beeClass.getClassFileVersion().getMinor());
buf.add(beeClass.getClassFileVersion().getMajor()); buf.addU16(beeClass.getClassFileVersion().getMajor());
Set<NodeConstant> constantTree = constantTreeCreator.createConstantTree(beeClass); Set<NodeConstant> constantTree = constantTreeCreator.createConstantTree(beeClass);
ConstantPool constantPool = constantPoolCreator.createConstantPool(constantTree); ConstantPool constantPool = constantPoolCreator.createConstantPool(constantTree);
buf.add(constantPool.getBytes()); buf.addU16(constantPool.getLength());
buf.addU8(constantPool.getBytes());
printBytes(buf);
return buf.toBytes(); return buf.toBytes();
} }
//TODO remove
private void printBytes(ByteBuf buf) {
byte[] bytes = buf.toBytes();
int count = 0;
for (byte b : bytes) {
System.out.print(String.format("%2s", Integer.toHexString(b & 0xFF)).replace(' ', '0') + (count % 2 == 0 ? "" : " "));
if (++count > 15) {
count = 0;
System.out.println();
}
}
}
} }

View file

@ -15,7 +15,7 @@ public class ConstantPoolCreator {
public ConstantPool createConstantPool(Set<NodeConstant> constantTree) { public ConstantPool createConstantPool(Set<NodeConstant> constantTree) {
constantPool = new ConstantPool(); constantPool = new ConstantPool();
constantPool.add(null); // dummy element to align it's index with the indexes in the elements themselves // constantPool.add(null); // dummy element to align it's index with the indexes in the elements themselves
index = 0; index = 0;
updateToplevelElements(constantTree); updateToplevelElements(constantTree);
return constantPool; return constantPool;

View file

@ -34,6 +34,7 @@ public class ConstantTreeCreator {
beeClass.getConstructors().forEach(this::updateConstantTree); beeClass.getConstructors().forEach(this::updateConstantTree);
// TODO update constantTree for fields ? // TODO update constantTree for fields ?
// TODO update constantTree for methods // TODO update constantTree for methods
constantTree.add(new ClassEntry(new Utf8Entry(internalName(beeClass.getName()))));
return constantTree; return constantTree;
} }
@ -55,23 +56,23 @@ public class ConstantTreeCreator {
} }
private void addMethod(CodeLine codeline) { private void addMethod(CodeLine codeline) {
constantTree.add(new ConstantMethodRef(createClassName(codeline), createMethodNameAndType(codeline))); constantTree.add(new MethodRefEntry(createClassName(codeline), createMethodNameAndType(codeline)));
} }
private void addField(CodeLine codeline) { private void addField(CodeLine codeline) {
constantTree.add(new ConstantFieldRef(createClassName(codeline), createFieldNameAndType(codeline))); constantTree.add(new FieldRefEntry(createClassName(codeline), createFieldNameAndType(codeline)));
} }
private ConstantNameAndType createMethodNameAndType(CodeLine codeline) { private NameAndTypeEntry createMethodNameAndType(CodeLine codeline) {
return new ConstantNameAndType(new ConstantUtf8(codeline.getMethodName()), new ConstantUtf8(codeline.getMethodSignature())); return new NameAndTypeEntry(new Utf8Entry(codeline.getMethodName()), new Utf8Entry(codeline.getMethodSignature()));
} }
private ConstantNameAndType createFieldNameAndType(CodeLine codeline) { private NameAndTypeEntry createFieldNameAndType(CodeLine codeline) {
return new ConstantNameAndType(new ConstantUtf8(codeline.getField().getName()), new ConstantUtf8(TypeMapper.map(codeline.getField().getType()))); return new NameAndTypeEntry(new Utf8Entry(codeline.getField().getName()), new Utf8Entry(TypeMapper.map(codeline.getField().getType())));
} }
private ConstantClass createClassName(CodeLine codeline) { private ClassEntry createClassName(CodeLine codeline) {
return new ConstantClass(new ConstantUtf8(internalName(getNameOfClass(codeline)))); return new ClassEntry(new Utf8Entry(internalName(getNameOfClass(codeline))));
} }
private String getNameOfClass(CodeLine codeline) { private String getNameOfClass(CodeLine codeline) {

View file

@ -24,7 +24,14 @@ public class ConstantPool {
public byte[] getBytes() { public byte[] getBytes() {
ByteBuf bytes = new ByteBuf(); ByteBuf bytes = new ByteBuf();
entries.forEach(entry -> bytes.add(entry.getBytes())); entries.forEach(entry -> bytes.addU8(entry.getBytes()));
return bytes.toBytes(); return bytes.toBytes();
} }
/**
* get the length +1
*/
public int getLength() {
return entries.size() + 1;
}
} }

View file

@ -1,10 +1,10 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantClass extends NodeConstant { public class ClassEntry extends NodeConstant {
private static final byte TAG = 7; private static final byte TAG = 7;
private final ConstantUtf8 name; private final Utf8Entry name;
public ConstantClass(ConstantUtf8 name) { public ClassEntry(Utf8Entry name) {
super(name); super(name);
this.name = name; this.name = name;
} }
@ -22,6 +22,6 @@ public class ConstantClass extends NodeConstant {
@Override @Override
public byte[] getBytes() { public byte[] getBytes() {
return new byte[]{TAG, upperFraction(getNameIndex()), lowerFraction(getNameIndex())}; return new byte[]{TAG, upperByte(getNameIndex()), lowerByte(getNameIndex())};
} }
} }

View file

@ -1,18 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantDouble extends LeafConstant {
private static final byte TAG = 6;
private final double doubleVal;
public ConstantDouble(double doubleVal) {
this.doubleVal = doubleVal;
}
@Override
public byte[] getBytes() {
long bits = Double.doubleToRawLongBits(doubleVal);
return new byte[]{TAG, rshift(bits, 56), rshift(bits, 48), rshift(bits, 40), rshift(bits, 32),
rshift(bits, 24), rshift(bits, 16), rshift(bits, 8), (byte) (bits & 0xFF)};
}
}

View file

@ -1,36 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantFieldRef extends NodeConstant {
private static final byte TAG = 9;
private final ConstantClass constantClass;
private final ConstantNameAndType constantNameAndType;
public ConstantFieldRef(ConstantClass constantClass, ConstantNameAndType constantNameAndType) {
super(constantClass, constantNameAndType);
this.constantClass = constantClass;
this.constantNameAndType = constantNameAndType;
}
public int getClassIndex() {
return constantClass.getIndex();
}
public int getNameAndTypeIndex() {
return constantNameAndType.getIndex();
}
@Override
public String toString() {
return "FieldRefEntry{" +
"classIndex=" + getClassIndex() +
", nameAndTypeIndex=" + getNameAndTypeIndex() +
'}';
}
@Override
public byte[] getBytes() {
return new byte[]{TAG};
}
}

View file

@ -1,28 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantInterfaceMethodRef extends NodeConstant {
private static final byte TAG = 11;
private final ConstantClass constantClass;
private final ConstantNameAndType constantNameAndType;
public ConstantInterfaceMethodRef(ConstantClass constantClass, ConstantNameAndType constantNameAndType) {
super(constantClass, constantNameAndType);
this.constantClass = constantClass;
this.constantNameAndType = constantNameAndType;
}
public int getClassIndex() {
return constantClass.getIndex();
}
public int getNameAndTypeIndex() {
return constantNameAndType.getIndex();
}
@Override
public byte[] getBytes() {
return new byte[]{TAG};
}
}

View file

@ -1,27 +0,0 @@
package nl.sander.beejava.constantpool.entry;
public class ConstantMethodRef extends NodeConstant {
private static final byte TAG = 10;
private final ConstantClass constantClass;
private final ConstantNameAndType constantNameAndType;
public ConstantMethodRef(ConstantClass constantClass, ConstantNameAndType constantNameAndType) {
super(constantClass, constantNameAndType);
this.constantClass = constantClass;
this.constantNameAndType = constantNameAndType;
}
public int getClassIndex() {
return constantClass.getIndex();
}
public int getNameAndTypeIndex() {
return constantNameAndType.getIndex();
}
public byte[] getBytes() {
return new byte[]{TAG};
}
}

View file

@ -0,0 +1,18 @@
package nl.sander.beejava.constantpool.entry;
public class DoubleEntry extends LeafConstant {
private static final byte TAG = 6;
private final double doubleVal;
public DoubleEntry(double doubleVal) {
this.doubleVal = doubleVal;
}
@Override
public byte[] getBytes() {
long bits = Double.doubleToRawLongBits(doubleVal);
return new byte[]{TAG, getByte(bits, 56), getByte(bits, 48), getByte(bits, 40), getByte(bits, 32),
getByte(bits, 24), getByte(bits, 16), getByte(bits, 8), (byte) (bits & 0xFF)};
}
}

View file

@ -1,11 +1,11 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantDynamic extends NodeConstant { public class DynamicEntry extends NodeConstant {
private static final byte TAG = 17; private static final byte TAG = 17;
private final int bootstrapMethodIndex; // TODO private final int bootstrapMethodIndex; // TODO
private final ConstantNameAndType nameAndType; private final NameAndTypeEntry nameAndType;
public ConstantDynamic(int bootstrapMethodIndex, ConstantNameAndType nameAndType) { public DynamicEntry(int bootstrapMethodIndex, NameAndTypeEntry nameAndType) {
this.bootstrapMethodIndex = bootstrapMethodIndex; this.bootstrapMethodIndex = bootstrapMethodIndex;
this.nameAndType = nameAndType; this.nameAndType = nameAndType;
} }

View file

@ -0,0 +1,36 @@
package nl.sander.beejava.constantpool.entry;
public class FieldRefEntry extends NodeConstant {
private static final byte TAG = 9;
private final ClassEntry classEntry;
private final NameAndTypeEntry nameAndTypeEntry;
public FieldRefEntry(ClassEntry classEntry, NameAndTypeEntry nameAndTypeEntry) {
super(classEntry, nameAndTypeEntry);
this.classEntry = classEntry;
this.nameAndTypeEntry = nameAndTypeEntry;
}
public int getClassIndex() {
return classEntry.getIndex();
}
public int getNameAndTypeIndex() {
return nameAndTypeEntry.getIndex();
}
@Override
public String toString() {
return "FieldRefEntry{" +
"classIndex=" + getClassIndex() +
", nameAndTypeIndex=" + getNameAndTypeIndex() +
'}';
}
@Override
public byte[] getBytes() {
return new byte[]{TAG};
}
}

View file

@ -1,11 +1,11 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantFloat extends LeafConstant { public class FloatEntry extends LeafConstant {
private static final byte TAG = 4; private static final byte TAG = 4;
private final float floatVal; private final float floatVal;
public ConstantFloat(float floatVal) { public FloatEntry(float floatVal) {
this.floatVal = floatVal; this.floatVal = floatVal;
} }

View file

@ -1,11 +1,11 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantInteger extends LeafConstant { public class IntegerEntry extends LeafConstant {
private static final byte TAG = 3; private static final byte TAG = 3;
private final int intVal; private final int intVal;
public ConstantInteger(int integer) { public IntegerEntry(int integer) {
this.intVal = integer; this.intVal = integer;
} }

View file

@ -0,0 +1,28 @@
package nl.sander.beejava.constantpool.entry;
public class InterfaceMethodRefEntry extends NodeConstant {
private static final byte TAG = 11;
private final ClassEntry classEntry;
private final NameAndTypeEntry nameAndTypeEntry;
public InterfaceMethodRefEntry(ClassEntry classEntry, NameAndTypeEntry nameAndTypeEntry) {
super(classEntry, nameAndTypeEntry);
this.classEntry = classEntry;
this.nameAndTypeEntry = nameAndTypeEntry;
}
public int getClassIndex() {
return classEntry.getIndex();
}
public int getNameAndTypeIndex() {
return nameAndTypeEntry.getIndex();
}
@Override
public byte[] getBytes() {
return new byte[]{TAG};
}
}

View file

@ -1,14 +1,14 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantInvokeDynamic extends NodeConstant { public class InvokeDynamicEntry extends NodeConstant {
private static final byte TAG = 18; private static final byte TAG = 18;
private final int bootstrapMethodAttrIndex; //?? private final int bootstrapMethodAttrIndex; //??
private final ConstantNameAndType constantNameAndType; private final NameAndTypeEntry nameAndTypeEntry;
public ConstantInvokeDynamic(int bootstrapMethodAttrIndex, ConstantNameAndType constantNameAndType) { public InvokeDynamicEntry(int bootstrapMethodAttrIndex, NameAndTypeEntry nameAndTypeEntry) {
this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex; this.bootstrapMethodAttrIndex = bootstrapMethodAttrIndex;
this.constantNameAndType = constantNameAndType; this.nameAndTypeEntry = nameAndTypeEntry;
} }
@ -16,7 +16,7 @@ public class ConstantInvokeDynamic extends NodeConstant {
public String toString() { public String toString() {
return "InvokeDynamicEntry{" + return "InvokeDynamicEntry{" +
"bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex + "bootstrapMethodAttrIndex=" + bootstrapMethodAttrIndex +
", nameAndTypeIndex=" + constantNameAndType.getIndex() + ", nameAndTypeIndex=" + nameAndTypeEntry.getIndex() +
'}'; '}';
} }

View file

@ -1,11 +1,11 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantLong extends LeafConstant { public class LongEntry extends LeafConstant {
private static final byte TAG = 5; private static final byte TAG = 5;
private final long longVal; private final long longVal;
public ConstantLong(long longVal) { public LongEntry(long longVal) {
this.longVal = longVal; this.longVal = longVal;
} }
@ -18,8 +18,8 @@ public class ConstantLong extends LeafConstant {
@Override @Override
public byte[] getBytes() { public byte[] getBytes() {
return new byte[]{TAG, rshift(longVal, 56), rshift(longVal, 48), rshift(longVal, 40), rshift(longVal, 32), return new byte[]{TAG, getByte(longVal, 56), getByte(longVal, 48), getByte(longVal, 40), getByte(longVal, 32),
rshift(longVal, 24), rshift(longVal, 16), rshift(longVal, 8), (byte) (longVal & 0xFF)}; getByte(longVal, 24), getByte(longVal, 16), getByte(longVal, 8), (byte) (longVal & 0xFF)};
} }

View file

@ -1,17 +1,17 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
//TODO implement later //TODO implement later
public class ConstantMethodHandle extends NodeConstant { public class MethodHandleEntry extends NodeConstant {
private static final byte TAG = 15; private static final byte TAG = 15;
private final int referenceKind; private final int referenceKind;
// only 1 of these can be present: // only 1 of these can be present:
private ConstantFieldRef constantFieldRef; private FieldRefEntry fieldRefEntry;
private ConstantMethodRef constantMethodRef; private MethodRefEntry methodRefEntry;
private ConstantInterfaceMethodRef constantInterfaceMethodRef; private InterfaceMethodRefEntry interfaceMethodRefEntry;
public ConstantMethodHandle(int referenceKind) { public MethodHandleEntry(int referenceKind) {
this.referenceKind = referenceKind; this.referenceKind = referenceKind;
} }

View file

@ -0,0 +1,27 @@
package nl.sander.beejava.constantpool.entry;
public class MethodRefEntry extends NodeConstant {
private static final byte TAG = 10;
private final ClassEntry classRef;
private final NameAndTypeEntry nameAndType;
public MethodRefEntry(ClassEntry classRef, NameAndTypeEntry nameAndType) {
super(classRef, nameAndType);
this.classRef = classRef;
this.nameAndType = nameAndType;
}
public int getClassIndex() {
return classRef.getIndex();
}
public int getNameAndTypeIndex() {
return nameAndType.getIndex();
}
public byte[] getBytes() {
return new byte[]{TAG, upperByte(getClassIndex()), lowerByte(getClassIndex()), upperByte(getNameAndTypeIndex()), lowerByte(getNameAndTypeIndex())};
}
}

View file

@ -1,11 +1,11 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantMethodType extends NodeConstant { public class MethodTypeEntry extends NodeConstant {
private static final byte TAG = 16; private static final byte TAG = 16;
private final ConstantUtf8 methodDescriptor; private final Utf8Entry methodDescriptor;
public ConstantMethodType(ConstantUtf8 methodDescriptor) { public MethodTypeEntry(Utf8Entry methodDescriptor) {
this.methodDescriptor = methodDescriptor; this.methodDescriptor = methodDescriptor;
} }

View file

@ -1,12 +1,12 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantModule extends NodeConstant { public class ModuleEntry extends NodeConstant {
private static final byte TAG = 19; private static final byte TAG = 19;
private final ConstantUtf8 nameEntry; private final Utf8Entry nameEntry;
public ConstantModule(ConstantUtf8 nameEntry) { public ModuleEntry(Utf8Entry nameEntry) {
super(nameEntry); super(nameEntry);
this.nameEntry = nameEntry; this.nameEntry = nameEntry;
} }
@ -16,6 +16,6 @@ public class ConstantModule extends NodeConstant {
} }
public byte[] getBytes() { public byte[] getBytes() {
return new byte[]{TAG, upperFraction(getNameIndex()), lowerFraction(getNameIndex())}; return new byte[]{TAG, upperByte(getNameIndex()), lowerByte(getNameIndex())};
} }
} }

View file

@ -1,11 +1,11 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantNameAndType extends NodeConstant { public class NameAndTypeEntry extends NodeConstant {
private static final byte TAG = 12; private static final byte TAG = 12;
private final ConstantUtf8 name; private final Utf8Entry name;
private final ConstantUtf8 descriptor; private final Utf8Entry descriptor;
public ConstantNameAndType(ConstantUtf8 name, ConstantUtf8 descriptor) { public NameAndTypeEntry(Utf8Entry name, Utf8Entry descriptor) {
super(name, descriptor); super(name, descriptor);
this.name = name; this.name = name;
this.descriptor = descriptor; this.descriptor = descriptor;
@ -29,6 +29,6 @@ public class ConstantNameAndType extends NodeConstant {
} }
public byte[] getBytes() { public byte[] getBytes() {
return new byte[]{TAG, upperFraction(getNameIndex()), lowerFraction(getNameIndex()), upperFraction(getDescriptorIndex()), lowerFraction(getDescriptorIndex())}; return new byte[]{TAG, upperByte(getNameIndex()), lowerByte(getNameIndex()), upperByte(getDescriptorIndex()), lowerByte(getDescriptorIndex())};
} }
} }

View file

@ -47,7 +47,7 @@ public abstract class NodeConstant {
* @param u16 is assumed to be 16 bits unsigned integer * @param u16 is assumed to be 16 bits unsigned integer
* @return lower 8 bits as byte * @return lower 8 bits as byte
*/ */
protected byte lowerFraction(int u16) { protected byte lowerByte(int u16) {
return (byte) (u16 & 0xFF); return (byte) (u16 & 0xFF);
} }
@ -57,11 +57,11 @@ public abstract class NodeConstant {
* @param u16 is assumed to be 16 bits unsigned integer * @param u16 is assumed to be 16 bits unsigned integer
* @return upper 8 bits as byte * @return upper 8 bits as byte
*/ */
protected byte upperFraction(int u16) { protected byte upperByte(int u16) {
return (byte) (u16 << 8); return (byte) (u16 << 8);
} }
protected byte rshift(long bits, int positions) { protected byte getByte(long bits, int positions) {
return (byte) (bits >>> positions); return (byte) ((bits >>> positions) & 0xFF);
} }
} }

View file

@ -1,10 +1,10 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantPackage extends NodeConstant { public class PackageEntry extends NodeConstant {
private static final byte TAG = 20; private static final byte TAG = 20;
private final ConstantUtf8 name; private final Utf8Entry name;
public ConstantPackage(ConstantUtf8 name) { public PackageEntry(Utf8Entry name) {
super(name); super(name);
this.name = name; this.name = name;
} }
@ -14,6 +14,6 @@ public class ConstantPackage extends NodeConstant {
} }
public byte[] getBytes() { public byte[] getBytes() {
return new byte[]{TAG, upperFraction(getNameIndex()), lowerFraction(getNameIndex())}; return new byte[]{TAG, upperByte(getNameIndex()), lowerByte(getNameIndex())};
} }
} }

View file

@ -1,10 +1,10 @@
package nl.sander.beejava.constantpool.entry; package nl.sander.beejava.constantpool.entry;
public class ConstantString extends NodeConstant { public class StringEntry extends NodeConstant {
private static final byte TAG = 8; private static final byte TAG = 8;
private final ConstantUtf8 utf8; private final Utf8Entry utf8;
public ConstantString(ConstantUtf8 utf8) { public StringEntry(Utf8Entry utf8) {
this.utf8 = utf8; this.utf8 = utf8;
} }
@ -20,6 +20,6 @@ public class ConstantString extends NodeConstant {
} }
public byte[] getBytes() { public byte[] getBytes() {
return new byte[]{TAG, upperFraction(getUtf8Index()), lowerFraction(getUtf8Index())}; return new byte[]{TAG, upperByte(getUtf8Index()), lowerByte(getUtf8Index())};
} }
} }

View file

@ -2,11 +2,11 @@ package nl.sander.beejava.constantpool.entry;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
public class ConstantUtf8 extends LeafConstant { public class Utf8Entry extends LeafConstant {
private static final byte TAG = 1; private static final byte TAG = 1;
private final String value; private final String value;
public ConstantUtf8(String utf8) { public Utf8Entry(String utf8) {
this.value = utf8; this.value = utf8;
} }
@ -25,8 +25,8 @@ public class ConstantUtf8 extends LeafConstant {
byte[] utf8Bytes = value.getBytes(StandardCharsets.UTF_8); byte[] utf8Bytes = value.getBytes(StandardCharsets.UTF_8);
byte[] bytes = new byte[utf8Bytes.length + 3]; byte[] bytes = new byte[utf8Bytes.length + 3];
bytes[0] = TAG; bytes[0] = TAG;
bytes[1] = upperFraction(bytes.length); bytes[1] = upperByte(bytes.length);
bytes[2] = lowerFraction(bytes.length); bytes[2] = lowerByte(bytes.length);
System.arraycopy(utf8Bytes, 0, bytes, 3, utf8Bytes.length); System.arraycopy(utf8Bytes, 0, bytes, 3, utf8Bytes.length);
return bytes; return bytes;
} }

View file

@ -42,29 +42,33 @@ public class ByteBuf {
data.clear(); data.clear();
} }
public void add(final byte c) { public void addU8(final byte c) {
if (data.remaining() == 0) { if (data.remaining() == 0) {
enlarge(1); enlarge(1);
} }
data.put(c); data.put(c);
} }
public void add(final byte[] bytes) { public void addU8(final byte[] bytes) {
if (data.remaining() < bytes.length) { if (data.remaining() < bytes.length) {
enlarge(bytes.length); enlarge(bytes.length);
} }
data.put(bytes); data.put(bytes);
} }
public void add(final int... ints) { public void addU8(final int... ints) {
if (data.remaining() < ints.length) { if (data.remaining() < ints.length) {
enlarge(ints.length); enlarge(ints.length);
} }
byte[] bytes = new byte[ints.length]; byte[] bytes = new byte[ints.length];
for (int i = 0; i < ints.length; i++) { for (int i = 0; i < ints.length; i++) {
bytes[i] = (byte) (i & 0xFF); bytes[i] = (byte) (ints[i] & 0xFF);
} }
add(bytes); addU8(bytes);
}
public void addU16(int u16) {
addU8((u16 >>> 8) & 0xFF, u16 & 0xFF);
} }
private void enlarge(final int size) { private void enlarge(final int size) {
@ -76,11 +80,11 @@ public class ByteBuf {
data = newData; data = newData;
} }
public int length() {
return data.limit() - data.remaining();
}
public byte[] toBytes() { public byte[] toBytes() {
return data.array(); int length = data.limit() - data.remaining();
data.rewind();
byte[] arr = new byte[length];
data.get(arr);
return arr;
} }
} }

View file

@ -0,0 +1,10 @@
package nl.sander.beejava;
import org.junit.jupiter.api.Test;
public class CompilerTests {
@Test
public void test(){
Compiler.compile(TestData.emptyClass());
}
}

View file

@ -19,68 +19,49 @@ public class ConstantTreeCreatorTests {
// creates simplest class possible and checks the tree, that the ConstantTreeCreator emits // creates simplest class possible and checks the tree, that the ConstantTreeCreator emits
@Test // This is not a maintainable test @Test // This is not a maintainable test
public void testMethodRefEntryForSuperConstructor() { public void testMethodRefEntryForSuperConstructor() {
BeeClass classWithIntField = createEmptyClass(); BeeClass classWithIntField = TestData.emptyClass();
Set<NodeConstant> constantTree = new ConstantTreeCreator().createConstantTree(classWithIntField); Set<NodeConstant> constantTree = new ConstantTreeCreator().createConstantTree(classWithIntField);
assertEquals(1, constantTree.size()); assertEquals(1, constantTree.size());
NodeConstant superConstructor = constantTree.iterator().next(); NodeConstant superConstructor = constantTree.iterator().next();
assertEquals(ConstantMethodRef.class, superConstructor.getClass()); assertEquals(MethodRefEntry.class, superConstructor.getClass());
ConstantMethodRef constantMethodRef = (ConstantMethodRef) superConstructor; MethodRefEntry methodRefEntry = (MethodRefEntry) superConstructor;
Set<NodeConstant> methodRefEntryChildren = constantMethodRef.getChildren(); Set<NodeConstant> methodRefEntryChildren = methodRefEntry.getChildren();
assertEquals(2, methodRefEntryChildren.size()); assertEquals(2, methodRefEntryChildren.size());
Iterator<NodeConstant> firstChildren = methodRefEntryChildren.iterator(); Iterator<NodeConstant> firstChildren = methodRefEntryChildren.iterator();
NodeConstant child1 = firstChildren.next(); NodeConstant child1 = firstChildren.next();
assertEquals(ConstantClass.class, child1.getClass()); assertEquals(ClassEntry.class, child1.getClass());
ConstantClass constantClass = (ConstantClass) child1; ClassEntry classEntry = (ClassEntry) child1;
Set<NodeConstant> classEntryChildren = constantClass.getChildren(); Set<NodeConstant> classEntryChildren = classEntry.getChildren();
assertEquals(1, classEntryChildren.size()); assertEquals(1, classEntryChildren.size());
NodeConstant child2 = classEntryChildren.iterator().next(); NodeConstant child2 = classEntryChildren.iterator().next();
assertEquals(ConstantUtf8.class, child2.getClass()); assertEquals(Utf8Entry.class, child2.getClass());
ConstantUtf8 className = (ConstantUtf8) child2; Utf8Entry className = (Utf8Entry) child2;
assertEquals("java/lang/Object", className.getUtf8()); assertEquals("java/lang/Object", className.getUtf8());
NodeConstant child3 = firstChildren.next(); NodeConstant child3 = firstChildren.next();
assertEquals(ConstantNameAndType.class, child3.getClass()); assertEquals(NameAndTypeEntry.class, child3.getClass());
ConstantNameAndType constantNameAndType = (ConstantNameAndType) child3; NameAndTypeEntry nameAndTypeEntry = (NameAndTypeEntry) child3;
Set<NodeConstant> nameAndTypeEntryChildren = constantNameAndType.getChildren(); Set<NodeConstant> nameAndTypeEntryChildren = nameAndTypeEntry.getChildren();
assertEquals(2, nameAndTypeEntryChildren.size()); assertEquals(2, nameAndTypeEntryChildren.size());
Iterator<NodeConstant> nameAndTypeChildrenIterator = nameAndTypeEntryChildren.iterator(); Iterator<NodeConstant> nameAndTypeChildrenIterator = nameAndTypeEntryChildren.iterator();
NodeConstant child4 = nameAndTypeChildrenIterator.next(); NodeConstant child4 = nameAndTypeChildrenIterator.next();
assertEquals(ConstantUtf8.class, child4.getClass()); assertEquals(Utf8Entry.class, child4.getClass());
ConstantUtf8 name = (ConstantUtf8) child4; Utf8Entry name = (Utf8Entry) child4;
assertEquals("<init>", name.getUtf8()); assertEquals("<init>", name.getUtf8());
NodeConstant child5 = nameAndTypeChildrenIterator.next(); NodeConstant child5 = nameAndTypeChildrenIterator.next();
assertEquals(ConstantUtf8.class, child5.getClass()); assertEquals(Utf8Entry.class, child5.getClass());
ConstantUtf8 type = (ConstantUtf8) child5; Utf8Entry type = (Utf8Entry) child5;
assertEquals("()V", type.getUtf8()); assertEquals("()V", type.getUtf8());
} }
private BeeClass createEmptyClass() {
BeeConstructor constructor = BeeConstructor.builder()
.withAccessFlags(MethodAccessFlag.PUBLIC)
.withCode(
line(0, LOAD, Ref.THIS),
line(1, INVOKE, Ref.SUPER, "<init>", "()"),
line(5, RETURN))
.build();
return BeeClass.builder()
.withClassFileVersion(Version.V14)
.withPackage("nl.sander.beejava.test")
.withAccessFlags(PUBLIC)
.withSimpleName("EmptyBean")
.withSuperClass(Object.class) // Not mandatory, like in java sourcecode
.withConstructors(constructor) // There's no default constructor in beejava. The user must always add them
.build();
}
private BeeClass createClassWithIntField() { private BeeClass createClassWithIntField() {
BeeField intField = BeeField.builder() BeeField intField = BeeField.builder()
.withAccessFlags(FieldAccessFlag.PRIVATE) .withAccessFlags(FieldAccessFlag.PRIVATE)

View file

@ -0,0 +1,32 @@
package nl.sander.beejava;
import nl.sander.beejava.api.BeeClass;
import nl.sander.beejava.api.BeeConstructor;
import nl.sander.beejava.api.Ref;
import nl.sander.beejava.api.Version;
import nl.sander.beejava.flags.MethodAccessFlag;
import static nl.sander.beejava.api.CodeLine.line;
import static nl.sander.beejava.api.Opcode.*;
import static nl.sander.beejava.flags.ClassAccessFlag.PUBLIC;
public class TestData {
public static BeeClass emptyClass() {
BeeConstructor constructor = BeeConstructor.builder()
.withAccessFlags(MethodAccessFlag.PUBLIC)
.withCode(
line(0, LOAD, Ref.THIS),
line(1, INVOKE, Ref.SUPER, "<init>", "()"),
line(5, RETURN))
.build();
return BeeClass.builder()
.withClassFileVersion(Version.V14)
.withPackage("nl.sander.beejava.test")
.withAccessFlags(PUBLIC)
.withSimpleName("EmptyBean")
.withSuperClass(Object.class) // Not mandatory, like in java sourcecode
.withConstructors(constructor) // There's no default constructor in beejava. The user must always add them
.build();
}
}

View file

@ -11,39 +11,39 @@ public class TagCorrectnessTest {
@Test @Test
public void testSpec() { public void testSpec() {
assertEquals(1, utf8().getTag()); assertEquals(1, utf8().getTag());
assertEquals(3, new ConstantInteger(0).getTag()); assertEquals(3, new IntegerEntry(0).getTag());
assertEquals(4, new ConstantFloat(0).getTag()); assertEquals(4, new FloatEntry(0).getTag());
assertEquals(5, new ConstantLong(0).getTag()); assertEquals(5, new LongEntry(0).getTag());
assertEquals(6, new ConstantDouble(0).getTag()); assertEquals(6, new DoubleEntry(0).getTag());
assertEquals(7, classEntry().getTag()); assertEquals(7, classEntry().getTag());
assertEquals(8, new ConstantString(utf8()).getTag()); assertEquals(8, new StringEntry(utf8()).getTag());
assertEquals(9, fieldRef().getTag()); assertEquals(9, fieldRef().getTag());
assertEquals(10, new ConstantMethodRef(classEntry(), nameAndType()).getTag()); assertEquals(10, new MethodRefEntry(classEntry(), nameAndType()).getTag());
assertEquals(11, new ConstantInterfaceMethodRef(classEntry(), nameAndType()).getTag()); assertEquals(11, new InterfaceMethodRefEntry(classEntry(), nameAndType()).getTag());
assertEquals(12, nameAndType().getTag()); assertEquals(12, nameAndType().getTag());
assertEquals(15, new ConstantMethodHandle(0).getTag()); //TODO assertEquals(15, new MethodHandleEntry(0).getTag()); //TODO
assertEquals(16, new ConstantMethodType(utf8()).getTag()); //TODO assertEquals(16, new MethodTypeEntry(utf8()).getTag()); //TODO
assertEquals(17, new ConstantDynamic(0, nameAndType()).getTag()); //TODO assertEquals(17, new DynamicEntry(0, nameAndType()).getTag()); //TODO
assertEquals(18, new ConstantInvokeDynamic(0, nameAndType()).getTag()); //TODO assertEquals(18, new InvokeDynamicEntry(0, nameAndType()).getTag()); //TODO
assertEquals(19, new ConstantModule(utf8()).getTag()); assertEquals(19, new ModuleEntry(utf8()).getTag());
assertEquals(20, new ConstantPackage(utf8()).getTag()); assertEquals(20, new PackageEntry(utf8()).getTag());
} }
private ConstantFieldRef fieldRef() { private FieldRefEntry fieldRef() {
return new ConstantFieldRef(classEntry(), nameAndType()); return new FieldRefEntry(classEntry(), nameAndType());
} }
private ConstantNameAndType nameAndType() { private NameAndTypeEntry nameAndType() {
return new ConstantNameAndType(utf8(), utf8()); return new NameAndTypeEntry(utf8(), utf8());
} }
private ConstantClass classEntry() { private ClassEntry classEntry() {
return new ConstantClass(utf8()); return new ClassEntry(utf8());
} }
private ConstantUtf8 utf8() { private Utf8Entry utf8() {
return new ConstantUtf8(""); return new Utf8Entry("");
} }
} }