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.constantpool.ConstantPool;
|
||||
import nl.sander.beejava.constantpool.entry.NodeConstant;
|
||||
import nl.sander.beejava.flags.ClassAccessFlag;
|
||||
import nl.sander.beejava.util.ByteBuf;
|
||||
|
||||
import java.util.Set;
|
||||
|
|
@ -33,9 +34,14 @@ public class Compiler {
|
|||
|
||||
buf.addU16(constantPool.getLength());
|
||||
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);
|
||||
|
||||
return buf.toBytes();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ public class ConstantPoolCreator {
|
|||
|
||||
public ConstantPool createConstantPool(Set<NodeConstant> constantTree) {
|
||||
constantPool = new ConstantPool();
|
||||
// constantPool.add(null); // dummy element to align it's index with the indexes in the elements themselves
|
||||
index = 0;
|
||||
updateToplevelElements(constantTree);
|
||||
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.
|
||||
*
|
||||
* <p>
|
||||
* 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.
|
||||
*/
|
||||
|
|
@ -20,6 +20,9 @@ import java.util.Set;
|
|||
public class ConstantTreeCreator {
|
||||
private final Set<NodeConstant> constantTree = new LinkedHashSet<>();
|
||||
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.
|
||||
|
|
@ -34,10 +37,30 @@ public class ConstantTreeCreator {
|
|||
beeClass.getConstructors().forEach(this::updateConstantTree);
|
||||
// TODO update constantTree for fields ?
|
||||
// TODO update constantTree for methods
|
||||
constantTree.add(new ClassEntry(new Utf8Entry(internalName(beeClass.getName()))));
|
||||
|
||||
constantTree.add(getThisClassRef(beeClass));
|
||||
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) {
|
||||
codeContainer.getCode().forEach(this::updateConstantTree);
|
||||
}
|
||||
|
|
@ -46,7 +69,7 @@ public class ConstantTreeCreator {
|
|||
* scan code line for items that need adding to the constant pool
|
||||
*/
|
||||
private void updateConstantTree(CodeLine codeline) {
|
||||
if (codeline.hasMethod()){
|
||||
if (codeline.hasMethod()) {
|
||||
addMethod(codeline);
|
||||
}
|
||||
|
||||
|
|
@ -56,11 +79,11 @@ public class ConstantTreeCreator {
|
|||
}
|
||||
|
||||
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) {
|
||||
constantTree.add(new FieldRefEntry(createClassName(codeline), createFieldNameAndType(codeline)));
|
||||
constantTree.add(new FieldRefEntry(getOrCreateClassEntry(codeline), createFieldNameAndType(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())));
|
||||
}
|
||||
|
||||
private ClassEntry createClassName(CodeLine codeline) {
|
||||
return new ClassEntry(new Utf8Entry(internalName(getNameOfClass(codeline))));
|
||||
private ClassEntry getOrCreateClassEntry(CodeLine 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) {
|
||||
if (codeline.getRef() == Ref.SUPER) {
|
||||
return beeClass.getSuperClass().getName();
|
||||
} else if (codeline.getRef() == Ref.THIS) {
|
||||
return beeClass.getName();
|
||||
}
|
||||
throw new RuntimeException("shouldn't be here");
|
||||
private ClassEntry createClassEntry(String name) {
|
||||
return new ClassEntry(new Utf8Entry(internalName(name)));
|
||||
}
|
||||
|
||||
private String internalName(String name) {
|
||||
|
|
|
|||
|
|
@ -90,6 +90,10 @@ public class CodeLine {
|
|||
return ref;
|
||||
}
|
||||
|
||||
public boolean hasRef() {
|
||||
return ref != null;
|
||||
}
|
||||
|
||||
public boolean hasField() {
|
||||
return field != null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,25 +6,20 @@ import nl.sander.beejava.util.ByteBuf;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ConstantPool {
|
||||
private final List<NodeConstant> entries = new ArrayList<>();
|
||||
public class ConstantPool extends ArrayList<NodeConstant>{
|
||||
|
||||
public int getIndex(NodeConstant entry) {
|
||||
for (int i = 0; i < entries.size(); i++) {
|
||||
if (entries.get(i) == entry) {
|
||||
for (int i = 0; i < size(); i++) {
|
||||
if (get(i) == entry) {
|
||||
return i + 1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public void add(NodeConstant entry) {
|
||||
entries.add(entry);
|
||||
}
|
||||
|
||||
public byte[] getBytes() {
|
||||
ByteBuf bytes = new ByteBuf();
|
||||
entries.forEach(entry -> bytes.addU8(entry.getBytes()));
|
||||
forEach(entry -> bytes.addU8(entry.getBytes()));
|
||||
return bytes.toBytes();
|
||||
}
|
||||
|
||||
|
|
@ -32,6 +27,6 @@ public class ConstantPool {
|
|||
* get the length +1
|
||||
*/
|
||||
public int getLength() {
|
||||
return entries.size() + 1;
|
||||
return size() + 1;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
package nl.sander.beejava.flags;
|
||||
|
||||
import nl.sander.beejava.flags.AccessFlag;
|
||||
import java.util.Collection;
|
||||
|
||||
public enum ClassAccessFlag implements AccessFlag {
|
||||
PUBLIC(0x0001), // Declared public; may be accessed from outside its package.
|
||||
|
|
@ -13,10 +13,15 @@ public enum ClassAccessFlag implements AccessFlag {
|
|||
ENUM(0x4000), // Declared as an enum type.
|
||||
MODULE(0x8000); // Is a module, not a class or interface.
|
||||
|
||||
|
||||
private final 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
|
||||
|
|
|
|||
|
|
@ -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