added refs to this and super
This commit is contained in:
parent
50649ea1a8
commit
3e699d0754
7 changed files with 92 additions and 29 deletions
|
|
@ -3,6 +3,7 @@ package nl.sander.beejava;
|
||||||
import nl.sander.beejava.api.BeeClass;
|
import nl.sander.beejava.api.BeeClass;
|
||||||
import nl.sander.beejava.constantpool.ConstantPool;
|
import nl.sander.beejava.constantpool.ConstantPool;
|
||||||
import nl.sander.beejava.constantpool.entry.NodeConstant;
|
import nl.sander.beejava.constantpool.entry.NodeConstant;
|
||||||
|
import nl.sander.beejava.flags.ClassAccessFlag;
|
||||||
import nl.sander.beejava.util.ByteBuf;
|
import nl.sander.beejava.util.ByteBuf;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
@ -33,9 +34,14 @@ public class Compiler {
|
||||||
|
|
||||||
buf.addU16(constantPool.getLength());
|
buf.addU16(constantPool.getLength());
|
||||||
buf.addU8(constantPool.getBytes());
|
buf.addU8(constantPool.getBytes());
|
||||||
|
buf.addU16(ClassAccessFlag.getSum(beeClass.getAccessFlags()));
|
||||||
|
buf.addU16(constantTreeCreator.getThisClass().getIndex());
|
||||||
|
buf.addU16(constantTreeCreator.getSuperClass().getIndex());
|
||||||
|
|
||||||
|
int x = 1;
|
||||||
|
for (NodeConstant e : constantPool) {
|
||||||
|
System.out.println((x++) + ":" + e);
|
||||||
|
}
|
||||||
printBytes(buf);
|
printBytes(buf);
|
||||||
|
|
||||||
return buf.toBytes();
|
return buf.toBytes();
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ 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
|
|
||||||
index = 0;
|
index = 0;
|
||||||
updateToplevelElements(constantTree);
|
updateToplevelElements(constantTree);
|
||||||
return constantPool;
|
return constantPool;
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import java.util.Set;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds a set of a tree of constant pool entries that refer to each other.
|
* Builds a set of a tree of constant pool entries that refer to each other.
|
||||||
*
|
* <p>
|
||||||
* A client must supply a {@link BeeClass} containing a set of {@link CodeLine}s that is assumed to be correct.
|
* A client must supply a {@link BeeClass} containing a set of {@link CodeLine}s that is assumed to be correct.
|
||||||
* It doesn't check if a valid state is reached.
|
* It doesn't check if a valid state is reached.
|
||||||
*/
|
*/
|
||||||
|
|
@ -20,6 +20,9 @@ import java.util.Set;
|
||||||
public class ConstantTreeCreator {
|
public class ConstantTreeCreator {
|
||||||
private final Set<NodeConstant> constantTree = new LinkedHashSet<>();
|
private final Set<NodeConstant> constantTree = new LinkedHashSet<>();
|
||||||
private BeeClass beeClass;
|
private BeeClass beeClass;
|
||||||
|
private ClassEntry thisClass;
|
||||||
|
private ClassEntry superClass;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Set of nested entries that make up a single reference. For instance a class reference whose name is a utf8 reference.
|
* Creates a Set of nested entries that make up a single reference. For instance a class reference whose name is a utf8 reference.
|
||||||
|
|
@ -34,10 +37,30 @@ 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()))));
|
|
||||||
|
constantTree.add(getThisClassRef(beeClass));
|
||||||
return constantTree;
|
return constantTree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* might be null if no methods refer to _this_
|
||||||
|
*/
|
||||||
|
private ClassEntry getThisClassRef(BeeClass beeClass) {
|
||||||
|
if (thisClass == null) {
|
||||||
|
thisClass = new ClassEntry(new Utf8Entry(internalName(beeClass.getName())));
|
||||||
|
}
|
||||||
|
return thisClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public ClassEntry getThisClass() {
|
||||||
|
return thisClass;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ClassEntry getSuperClass() {
|
||||||
|
return superClass;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateConstantTree(ContainsCode codeContainer) {
|
private void updateConstantTree(ContainsCode codeContainer) {
|
||||||
codeContainer.getCode().forEach(this::updateConstantTree);
|
codeContainer.getCode().forEach(this::updateConstantTree);
|
||||||
}
|
}
|
||||||
|
|
@ -56,11 +79,11 @@ public class ConstantTreeCreator {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMethod(CodeLine codeline) {
|
private void addMethod(CodeLine codeline) {
|
||||||
constantTree.add(new MethodRefEntry(createClassName(codeline), createMethodNameAndType(codeline)));
|
constantTree.add(new MethodRefEntry(getOrCreateClassEntry(codeline), createMethodNameAndType(codeline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addField(CodeLine codeline) {
|
private void addField(CodeLine codeline) {
|
||||||
constantTree.add(new FieldRefEntry(createClassName(codeline), createFieldNameAndType(codeline)));
|
constantTree.add(new FieldRefEntry(getOrCreateClassEntry(codeline), createFieldNameAndType(codeline)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private NameAndTypeEntry createMethodNameAndType(CodeLine codeline) {
|
private NameAndTypeEntry createMethodNameAndType(CodeLine codeline) {
|
||||||
|
|
@ -71,17 +94,24 @@ public class ConstantTreeCreator {
|
||||||
return new NameAndTypeEntry(new Utf8Entry(codeline.getField().getName()), new Utf8Entry(TypeMapper.map(codeline.getField().getType())));
|
return new NameAndTypeEntry(new Utf8Entry(codeline.getField().getName()), new Utf8Entry(TypeMapper.map(codeline.getField().getType())));
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClassEntry createClassName(CodeLine codeline) {
|
private ClassEntry getOrCreateClassEntry(CodeLine codeline) {
|
||||||
return new ClassEntry(new Utf8Entry(internalName(getNameOfClass(codeline))));
|
if (codeline.getRef() == Ref.SUPER) {
|
||||||
|
if (superClass == null) {
|
||||||
|
superClass = createClassEntry(beeClass.getSuperClass().getName());
|
||||||
|
}
|
||||||
|
return superClass;
|
||||||
|
} else if (codeline.getRef() == Ref.THIS) {
|
||||||
|
if (thisClass == null) {
|
||||||
|
thisClass = createClassEntry(beeClass.getName());
|
||||||
|
}
|
||||||
|
return thisClass;
|
||||||
|
}
|
||||||
|
//TODO other cases
|
||||||
|
throw new RuntimeException("shouldn't be here");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNameOfClass(CodeLine codeline) {
|
private ClassEntry createClassEntry(String name) {
|
||||||
if (codeline.getRef() == Ref.SUPER) {
|
return new ClassEntry(new Utf8Entry(internalName(name)));
|
||||||
return beeClass.getSuperClass().getName();
|
|
||||||
} else if (codeline.getRef() == Ref.THIS) {
|
|
||||||
return beeClass.getName();
|
|
||||||
}
|
|
||||||
throw new RuntimeException("shouldn't be here");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String internalName(String name) {
|
private String internalName(String name) {
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,10 @@ public class CodeLine {
|
||||||
return ref;
|
return ref;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasRef() {
|
||||||
|
return ref != null;
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasField() {
|
public boolean hasField() {
|
||||||
return field != null;
|
return field != null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,25 +6,20 @@ import nl.sander.beejava.util.ByteBuf;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ConstantPool {
|
public class ConstantPool extends ArrayList<NodeConstant>{
|
||||||
private final List<NodeConstant> entries = new ArrayList<>();
|
|
||||||
|
|
||||||
public int getIndex(NodeConstant entry) {
|
public int getIndex(NodeConstant entry) {
|
||||||
for (int i = 0; i < entries.size(); i++) {
|
for (int i = 0; i < size(); i++) {
|
||||||
if (entries.get(i) == entry) {
|
if (get(i) == entry) {
|
||||||
return i + 1;
|
return i + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void add(NodeConstant entry) {
|
|
||||||
entries.add(entry);
|
|
||||||
}
|
|
||||||
|
|
||||||
public byte[] getBytes() {
|
public byte[] getBytes() {
|
||||||
ByteBuf bytes = new ByteBuf();
|
ByteBuf bytes = new ByteBuf();
|
||||||
entries.forEach(entry -> bytes.addU8(entry.getBytes()));
|
forEach(entry -> bytes.addU8(entry.getBytes()));
|
||||||
return bytes.toBytes();
|
return bytes.toBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -32,6 +27,6 @@ public class ConstantPool {
|
||||||
* get the length +1
|
* get the length +1
|
||||||
*/
|
*/
|
||||||
public int getLength() {
|
public int getLength() {
|
||||||
return entries.size() + 1;
|
return size() + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
package nl.sander.beejava.flags;
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
import nl.sander.beejava.flags.AccessFlag;
|
import java.util.Collection;
|
||||||
|
|
||||||
public enum ClassAccessFlag implements AccessFlag {
|
public enum ClassAccessFlag implements AccessFlag {
|
||||||
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
||||||
|
|
@ -13,12 +13,17 @@ public enum ClassAccessFlag implements AccessFlag {
|
||||||
ENUM(0x4000), // Declared as an enum type.
|
ENUM(0x4000), // Declared as an enum type.
|
||||||
MODULE(0x8000); // Is a module, not a class or interface.
|
MODULE(0x8000); // Is a module, not a class or interface.
|
||||||
|
|
||||||
|
|
||||||
private final int bytecode;
|
private final int bytecode;
|
||||||
|
|
||||||
ClassAccessFlag(int bytecode) {
|
ClassAccessFlag(int bytecode) {
|
||||||
this.bytecode = bytecode;
|
this.bytecode = bytecode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int getSum(Collection<ClassAccessFlag> flags) {
|
||||||
|
return flags.stream().mapToInt(ClassAccessFlag::getBytecode).reduce(0, (result, value) -> result | value);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBytecode() {
|
public int getBytecode() {
|
||||||
return bytecode;
|
return bytecode;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
package nl.sander.beejava.flags;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Assertions;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
|
||||||
|
public class ClassAccessFlagTest {
|
||||||
|
@Test
|
||||||
|
public void mustOr1Value() {
|
||||||
|
assertEquals(1, ClassAccessFlag.getSum(Collections.singletonList(ClassAccessFlag.PUBLIC)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mustOr2Values() {
|
||||||
|
assertEquals(17, ClassAccessFlag.getSum(Arrays.asList(ClassAccessFlag.PUBLIC, ClassAccessFlag.FINAL)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Add table
Reference in a new issue