Skip to content
This repository was archived by the owner on Feb 17, 2022. It is now read-only.

Commit a96de4a

Browse files
committed
Methods?
1 parent e98a48d commit a96de4a

File tree

4 files changed

+126
-5
lines changed

4 files changed

+126
-5
lines changed

src/main/java/io/github/seggan/javaclasslib/JavaClass.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.github.seggan.javaclasslib.constantpool.ClassEntry;
44
import io.github.seggan.javaclasslib.constantpool.ConstantPoolEntry;
55
import io.github.seggan.javaclasslib.constantpool.UTF8Entry;
6+
import io.github.seggan.javaclasslib.methods.Method;
67

78
import javax.annotation.Nonnull;
89
import java.io.IOException;
@@ -21,7 +22,7 @@ public final class JavaClass {
2122
private final ClassEntry thisClass;
2223
private final ClassEntry superClass;
2324
private final int classVersion;
24-
25+
private final List<Method> methods = new LinkedList<>();
2526
private ClassAccessFlags[] classAccessFlags = new ClassAccessFlags[0];
2627

2728
public JavaClass(@Nonnull String name, @Nonnull String superclass, int javaVersion) {
@@ -44,6 +45,12 @@ public void write(@Nonnull OutputStream out) throws IOException {
4445
out.write(ByteUtils.twoBytesFromInt(ClassAccessFlags.combine(classAccessFlags)));
4546
out.write(thisClass.getIndexBytes());
4647
out.write(superClass.getIndexBytes());
48+
out.write(new byte[]{0, 0});
49+
out.write(ByteUtils.twoBytesFromInt(methods.size()));
50+
for (Method method : methods) {
51+
out.write(method.getBytes());
52+
}
53+
out.write(0);
4754
}
4855

4956
public List<ConstantPoolEntry> getConstantPool() {
@@ -69,4 +76,8 @@ public ClassAccessFlags[] getClassAccessFlags() {
6976
public void setClassAccessFlags(ClassAccessFlags... classAccessFlags) {
7077
this.classAccessFlags = classAccessFlags;
7178
}
79+
80+
public List<Method> getMethods() {
81+
return methods;
82+
}
7283
}
Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
package io.github.seggan.javaclasslib.attributes.code;
22

33
import com.google.common.primitives.Bytes;
4+
import io.github.seggan.javaclasslib.ByteUtils;
45
import io.github.seggan.javaclasslib.attributes.Attribute;
56
import io.github.seggan.javaclasslib.constantpool.UTF8Entry;
67

8+
import java.io.ByteArrayOutputStream;
9+
import java.util.List;
10+
711
public final class CodeAttribute extends Attribute {
812

913
private final int maxStackSize;
1014
private final int maxLocalVarSize;
11-
private final JvmInstructionImpl[] code;
15+
private final List<JvmInstructionImpl> code;
1216

13-
public CodeAttribute(UTF8Entry nameIndex, int length, int maxStackSize, int maxLocalVarSize, JvmInstructionImpl... code) {
17+
public CodeAttribute(UTF8Entry nameIndex, int length, int maxStackSize, int maxLocalVarSize, List<JvmInstructionImpl> code) {
1418
super(nameIndex, "Code", length);
1519
this.maxStackSize = maxStackSize;
1620
this.maxLocalVarSize = maxLocalVarSize;
@@ -19,7 +23,23 @@ public CodeAttribute(UTF8Entry nameIndex, int length, int maxStackSize, int maxL
1923

2024
@Override
2125
public byte[] getBytes() {
22-
return Bytes.concat();
26+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
27+
for (JvmInstructionImpl instruction : code) {
28+
for (byte b : instruction.getBytes()) {
29+
outputStream.write(b);
30+
}
31+
}
32+
byte[] codeByteArray = outputStream.toByteArray();
33+
34+
byte[] attribute = Bytes.concat(
35+
ByteUtils.twoBytesFromInt(maxStackSize),
36+
ByteUtils.twoBytesFromInt(maxLocalVarSize),
37+
ByteUtils.intToBytes(codeByteArray.length),
38+
codeByteArray,
39+
new byte[]{0, 0, 0, 0}
40+
);
41+
42+
return Bytes.concat(getNameIndex().getIndexBytes(), ByteUtils.intToBytes(attribute.length), attribute);
2343
}
2444

2545
public int getMaxStackSize() {
@@ -30,7 +50,7 @@ public int getMaxLocalVarSize() {
3050
return maxLocalVarSize;
3151
}
3252

33-
public JvmInstructionImpl[] getCode() {
53+
public List<JvmInstructionImpl> getCode() {
3454
return code;
3555
}
3656
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.github.seggan.javaclasslib.methods;
2+
3+
import com.google.common.primitives.Bytes;
4+
import io.github.seggan.javaclasslib.ByteUtils;
5+
import io.github.seggan.javaclasslib.attributes.Attribute;
6+
import io.github.seggan.javaclasslib.constantpool.UTF8Entry;
7+
8+
import javax.annotation.Nonnull;
9+
import java.io.ByteArrayOutputStream;
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
13+
public final class Method {
14+
15+
private final UTF8Entry name;
16+
private final UTF8Entry descriptor;
17+
private final List<Attribute> attributes = new ArrayList<>();
18+
19+
private MethodAccessFlags[] accessFlags = new MethodAccessFlags[0];
20+
21+
public Method(UTF8Entry name, UTF8Entry descriptor) {
22+
this.name = name;
23+
this.descriptor = descriptor;
24+
}
25+
26+
@Nonnull
27+
public byte[] getBytes() {
28+
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
29+
for (Attribute attribute : attributes) {
30+
for (byte b : attribute.getBytes()) {
31+
outputStream.write(b);
32+
}
33+
}
34+
35+
return Bytes.concat(ByteUtils.twoBytesFromInt(MethodAccessFlags.combine(accessFlags)), name.getIndexBytes(),
36+
descriptor.getIndexBytes(), ByteUtils.twoBytesFromInt(attributes.size()), outputStream.toByteArray());
37+
}
38+
39+
public UTF8Entry getName() {
40+
return name;
41+
}
42+
43+
public UTF8Entry getDescriptor() {
44+
return descriptor;
45+
}
46+
47+
public List<Attribute> getAttributes() {
48+
return attributes;
49+
}
50+
51+
public MethodAccessFlags[] getAccessFlags() {
52+
return accessFlags;
53+
}
54+
55+
public void setAccessFlags(MethodAccessFlags[] accessFlags) {
56+
this.accessFlags = accessFlags;
57+
}
58+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package io.github.seggan.javaclasslib.methods;
2+
3+
import java.util.Arrays;
4+
5+
public enum MethodAccessFlags {
6+
PUBLIC(0x0001),
7+
PRIVATE(0x0002),
8+
PROTECTED(0x0004),
9+
STATIC(0x0008),
10+
FINAL(0x0010),
11+
SYNCHRONIZED(0x0020),
12+
BRIDGE(0x0040),
13+
VARAGRGS(0x0080),
14+
NATIVE(0x0100),
15+
ABSTRACT(0x0400),
16+
STRICT(0x0800),
17+
SYNTHETIC(0x1000);
18+
19+
private final int value;
20+
21+
MethodAccessFlags(int value) {
22+
this.value = value;
23+
}
24+
25+
public static int combine(MethodAccessFlags... flags) {
26+
return Arrays.stream(flags).mapToInt(MethodAccessFlags::getValue).sum();
27+
}
28+
29+
public int getValue() {
30+
return value;
31+
}
32+
}

0 commit comments

Comments
 (0)