Skip to content

Commit

Permalink
Introduction to the class File Format
Browse files Browse the repository at this point in the history
  • Loading branch information
yohanbeschi committed Jan 19, 2014
1 parent bfb804d commit 6ab1b0a
Show file tree
Hide file tree
Showing 10 changed files with 194 additions and 1 deletion.
@@ -0,0 +1,21 @@
package org.isk.jvmhardcore.pjba.structure;

import org.isk.jvmhardcore.pjba.structure.attribute.Attribute;

public class ClassFile {
final private int magic = 0xcafebabe;
final private int version = 0x30; // 48.0 = 0x00 (version mineure) | 0x30 (version majeur)
private int constantPoolCount;
private Constant.ConstantPoolEntry[] constantPool;
final private int accessFlags = 0x0001 | 0x0020; // public super;
private int thisClass;
private int superClass;
private int interfacesCount;
private int[] interfaces;
private int fieldsCount;
private Field[] fields;
private int methodsCount;
private Method[] methods;
private int attributesCount;
private Attribute[] attributes;
}
@@ -0,0 +1,98 @@
package org.isk.jvmhardcore.pjba.structure;

public class Constant {
public static abstract class ConstantPoolEntry {
final private int tag;

public ConstantPoolEntry(ConstantPoolTag tag) {
this.tag = tag.getValue();
}
}

public static class UTF8 extends ConstantPoolEntry {
final private java.lang.String value;

public UTF8(final java.lang.String value) {
super(ConstantPoolTag.UTF8);
this.value = value;
}
}

public static class Integer extends ConstantPoolEntry {
final private int integer;

public Integer(int integer) {
super(ConstantPoolTag.INTEGER);
this.integer = integer;
}
}

public static class Float extends ConstantPoolEntry {
final private float floatValue;

public Float(float floatValue) {
super(ConstantPoolTag.FLOAT);
this.floatValue = floatValue;
}
}

public static class Long extends ConstantPoolEntry {
final private long longValue;

public Long(long longValue) {
super(ConstantPoolTag.LONG);
this.longValue = longValue;
}
}

public static class Double extends ConstantPoolEntry {
final private double doubleValue;

public Double(double doubleValue) {
super(ConstantPoolTag.DOUBLE);
this.doubleValue = doubleValue;
}
}

public static class Class extends ConstantPoolEntry {
final private int nameIndex;

public Class(final int nameIndex) {
super(ConstantPoolTag.CLASS);
this.nameIndex = nameIndex;
}
}

public static class String extends ConstantPoolEntry {
final private int utf8Index;

public String(int stringIndex) {
super(ConstantPoolTag.STRING);
this.utf8Index = stringIndex;
}
}

public static enum ConstantPoolTag {
UTF8(1),
INTEGER(3),
FLOAT(4),
LONG(5),
DOUBLE(6),
CLASS(7),
STRING(8),
FIELDREF(9),
METHODREF(10),
INTERFACE_METHODREF(11),
NAME_AND_TYPE(12);

private int value;

private ConstantPoolTag(int value) {
this.value = value;
}

public int getValue() {
return this.value;
}
}
}
@@ -0,0 +1,5 @@
package org.isk.jvmhardcore.pjba.structure;

public class Exception {

}
@@ -0,0 +1,5 @@
package org.isk.jvmhardcore.pjba.structure;

public class Field {

}
@@ -0,0 +1,11 @@
package org.isk.jvmhardcore.pjba.structure;

import org.isk.jvmhardcore.pjba.structure.attribute.Attribute;

public class Method {
private int accessFlags = 0x0001 | 0x0008; // public static
private int nameIndex;
private int descriptorIndex;
private int attributesCount;
private Attribute[] attributes;
}
@@ -0,0 +1,10 @@
package org.isk.jvmhardcore.pjba.structure.attribute;

public abstract class Attribute {
final private int nameIndex;
private int attributeLength;

public Attribute(final int nameIndex) {
this.nameIndex = nameIndex;
}
}
@@ -0,0 +1,20 @@
package org.isk.jvmhardcore.pjba.structure.attribute;

import org.isk.jvmhardcore.pjba.structure.Exception;

public class Code extends Attribute {
public final static String ATTRIBUTE_NAME = "Code";

private int maxStack;
private int maxLocals;
private int codeLength;
private byte[] code;
private int exceptionsCount;
private Exception[] exceptions;
private int attributesCount;
private Attribute[] attributes;

public Code(final int attributeNameIndex) {
super(attributeNameIndex);
}
}
13 changes: 13 additions & 0 deletions 03_projects/pjba/build.xml
@@ -0,0 +1,13 @@
<project name="pjba" default="archive" xmlns:plume="http://blog.soat.fr/ant-macros">
<import file="../../01_conf/targets.xml" />
<description>Plume Java Bytecode Assembler</description>

<target name="compile" depends="-init">
<echo>Compiling Main</echo>
<plume:compiler srcDir="${src.main.java.dir}" destDir="${build.classes.dir}" />
</target>

<target name="test" depends="compile">
<!-- Do nothing for now -->
</target>
</project>
11 changes: 10 additions & 1 deletion README.md
Expand Up @@ -222,4 +222,13 @@ Unicode and Java.
### Compile and execute
The project can only be executed through unit tests. (See introduction)

Blog post: [Part 10 - L'unicode et Java](http://blog.soat.fr/2014/01/jvm-hardcore-part-10-unicode-et-java)
Blog post: [JVM Hardcore - Part 10 - L'unicode et Java](http://blog.soat.fr/2014/01/11-jvm-hardcore-part-10-unicode-et-java)

## part11
### Summary
Introduction to the `class` File Format.

### Compile and execute
Nothing to test. The project **pjba** contains only beans representing the structure of a class file.

Blog post: [JVM Hardcore - Part 11 - Bytecode - Format d'un fichier .class](http://blog.soat.fr/2014/01/12-jvm-hardcore-part-11-bytecode-format-fichier-class)
1 change: 1 addition & 0 deletions build.xml
Expand Up @@ -13,6 +13,7 @@
<ant dir="${projects.dir}/bytecode/" target="${target}" inheritAll="false" />
<ant dir="${projects.dir}/mathparser/" target="${target}" inheritAll="false" />
<ant dir="${projects.dir}/encoding/" target="${target}" inheritAll="false"/>
<ant dir="${projects.dir}/pjba/" target="${target}" inheritAll="false" />
</target>

<target name="nop" description="Checks projects build">
Expand Down

0 comments on commit 6ab1b0a

Please sign in to comment.