Skip to content

Commit e932b05

Browse files
committed
Added more tests and code cleanups
1 parent 64b02ad commit e932b05

44 files changed

Lines changed: 352 additions & 135 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

README.md

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,15 @@ The framework leverages the Java Class-File API introduced in Java 24 (JEP 484).
1818
- Implements Sea-of-Nodes IR design
1919
- Further examples and documentation: [SeaOfNodes/Simple](https://github.com/SeaOfNodes/Simple)
2020

21-
> 🚧 Scheduling logic for machine code transformation is under development.
21+
> * 🚧 Scheduling logic for machine code transformation is under development.
22+
> * 🚧 Exception handling is under development.
23+
24+
## Credits
25+
- An excellent tutorial about the Class-File API: [Build A Compiler With The Java Class-File API by Dr. James Hamilton](https://jameshamilton.eu/programming/build-compiler-java-class-file-api)
2226

2327
## Example new instance creation
2428

25-
A simple Java example with constructor invocation, demonstrating the use of
29+
A simple Java example with constructor invoke, demonstrating the use of
2630
the JUnit Platform integration:
2731

2832
```
@@ -34,7 +38,8 @@ public class NewInstanceTest {
3438
public void newInstance() {
3539
new NewInstanceTest();
3640
}
37-
}``
41+
}
42+
```
3843

3944
Class-File API Debug YAML:
4045
```
@@ -58,7 +63,6 @@ Class-File API Debug YAML:
5863
4: {opcode: INVOKESPECIAL, owner: de/mirkosertic/metair/ir/examples/NewInstanceTest, method name: <init>, method type: ()V}
5964
7: {opcode: POP}
6065
8: {opcode: RETURN}
61-
6266
```
6367

6468
Generated IR (raw and unoptimized):
@@ -91,14 +95,6 @@ TODO: Add links to examples repository
9195
*/
9296
RET(RawBytecodeHelper.RET, 2, Kind.DISCONTINUED_RET),
9397

94-
/**
95-
* Invoke a dynamically-computed call site.
96-
*
97-
* @jvms 6.5.invokedynamic <em>invokedynamic</em>
98-
* @see Kind#INVOKE_DYNAMIC
99-
*/
100-
INVOKEDYNAMIC(RawBytecodeHelper.INVOKEDYNAMIC, 5, Kind.INVOKE_DYNAMIC),
101-
10298
/**
10399
* (Discontinued) Jump subroutine (wide index); last used in major
104100
* version {@value ClassFile#JAVA_6_VERSION}.

src/main/java/de/mirkosertic/metair/ir/ArrayLength.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ public class ArrayLength extends Value {
77
ArrayLength(final Value array) {
88
super(ConstantDescs.CD_int);
99

10-
if (!array.type.isArray()) {
10+
if (!array.isArray()) {
1111
illegalArgument("Cannot get array length of non array of type " + TypeUtils.toString(array.type));
1212
}
1313

src/main/java/de/mirkosertic/metair/ir/ArrayLoad.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class ArrayLoad extends Value {
1010
ArrayLoad(final ClassDesc arrayType, final Value array, final Value index) {
1111
super(arrayType.componentType());
1212

13-
if (!array.type.isArray()) {
13+
if (!array.isArray()) {
1414
illegalArgument("Cannot store to non array of type " + TypeUtils.toString(array.type));
1515
}
1616

src/main/java/de/mirkosertic/metair/ir/ArrayStore.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ public class ArrayStore extends Node {
88
public final ClassDesc arrayType;
99

1010
ArrayStore(final Value array, final Value index, final Value value) {
11-
if (!array.type.isArray()) {
11+
if (!array.isArray()) {
1212
illegalArgument("Cannot store to non array of type " + TypeUtils.toString(array.type));
1313
}
1414

15+
arrayType = (ClassDesc) array.type;
16+
1517
if (!index.type.equals(ConstantDescs.CD_int)) {
1618
illegalArgument("Cannot store to non int index of type " + TypeUtils.toString(index.type));
1719
}
1820

19-
if (array.type.componentType().isPrimitive() && !value.type.equals(array.type.componentType())) {
20-
illegalArgument("Cannot store non " + TypeUtils.toString(array.type.componentType()) + " value " + TypeUtils.toString(value.type) + " to array of type " + TypeUtils.toString(array.type));
21+
if (arrayType.componentType().isPrimitive() && !value.type.equals(arrayType.componentType())) {
22+
illegalArgument("Cannot store non " + TypeUtils.toString(arrayType.componentType()) + " value " + TypeUtils.toString(value.type) + " to array of type " + TypeUtils.toString(array.type));
2123
}
2224

23-
this.arrayType = array.type;
24-
2525
use(array, new ArgumentUse(0));
2626
use(index, new ArgumentUse(1));
2727
use(value, new ArgumentUse(2));
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package de.mirkosertic.metair.ir;
2+
3+
import java.lang.constant.ConstantDesc;
4+
5+
public abstract class ConstantValue extends Value {
6+
7+
ConstantValue(final ConstantDesc type) {
8+
super(type);
9+
}
10+
11+
@Override
12+
public boolean isConstant() {
13+
return true;
14+
}
15+
}

src/main/java/de/mirkosertic/metair/ir/DOTExporter.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ private static void printNode(final int index, final Node node, final PrintStrea
199199

200200
private static void printNode(final String shape, final int index, final Node node, final PrintStream ps, final String labelSuffex) {
201201
ps.print("label=\"#" + index + " " + node.debugDescription() + labelSuffex + "\"");
202-
if (node instanceof Method || node instanceof LabelNode || node instanceof Return || node instanceof ReturnValue || node instanceof Goto || node instanceof If || node instanceof Copy || node instanceof Invocation || node instanceof ClassInitialization || node instanceof MonitorEnter || node instanceof MonitorExit || node instanceof Throw || node instanceof ArrayStore || node instanceof ArrayLoad || node instanceof CheckCast || node instanceof PutField || node instanceof PutStatic || node instanceof MergeNode || node instanceof Projection || node instanceof LoopHeaderNode || node instanceof TableSwitch || node instanceof LookupSwitch) {
202+
if (node instanceof Method || node instanceof LabelNode || node instanceof Return || node instanceof ReturnValue || node instanceof Goto || node instanceof If || node instanceof Copy || node instanceof Invoke || node instanceof ClassInitialization || node instanceof MonitorEnter || node instanceof MonitorExit || node instanceof Throw || node instanceof ArrayStore || node instanceof ArrayLoad || node instanceof CheckCast || node instanceof PutField || node instanceof PutStatic || node instanceof MergeNode || node instanceof Projection || node instanceof LoopHeaderNode || node instanceof TableSwitch || node instanceof LookupSwitch) {
203203
ps.print(",shape=" + shape +", fillcolor=lightgrey, style=filled");
204204
} else if (node.isConstant()) {
205205
ps.print(",shape=octagon, fillcolor=lightgreen, style=filled");
@@ -210,7 +210,7 @@ private static void printNode(final String shape, final int index, final Node no
210210

211211
private static void printNodeWithLabel(final String label, final String shape, final Node node, final PrintStream ps) {
212212
ps.print("label=" + label);
213-
if (node instanceof Method || node instanceof LabelNode || node instanceof Return || node instanceof ReturnValue || node instanceof Goto || node instanceof If || node instanceof Copy || node instanceof Invocation || node instanceof ClassInitialization || node instanceof MonitorEnter || node instanceof MonitorExit || node instanceof Throw || node instanceof ArrayStore || node instanceof ArrayLoad || node instanceof CheckCast || node instanceof PutField || node instanceof PutStatic || node instanceof MergeNode || node instanceof Projection || node instanceof LoopHeaderNode || node instanceof TableSwitch || node instanceof LookupSwitch) {
213+
if (node instanceof Method || node instanceof LabelNode || node instanceof Return || node instanceof ReturnValue || node instanceof Goto || node instanceof If || node instanceof Copy || node instanceof Invoke || node instanceof ClassInitialization || node instanceof MonitorEnter || node instanceof MonitorExit || node instanceof Throw || node instanceof ArrayStore || node instanceof ArrayLoad || node instanceof CheckCast || node instanceof PutField || node instanceof PutStatic || node instanceof MergeNode || node instanceof Projection || node instanceof LoopHeaderNode || node instanceof TableSwitch || node instanceof LookupSwitch) {
214214
ps.print(",shape=" + shape +", fillcolor=lightgrey, style=filled");
215215
} else if (node.isConstant()) {
216216
ps.print(",shape=octagon, fillcolor=lightgreen, style=filled");

src/main/java/de/mirkosertic/metair/ir/ExtractMethodArgProjection.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package de.mirkosertic.metair.ir;
22

3-
import java.lang.constant.ClassDesc;
3+
import java.lang.constant.ConstantDesc;
44

55
public class ExtractMethodArgProjection extends Value implements Projection {
66

77
private final int index;
88

9-
ExtractMethodArgProjection(final ClassDesc type, final int index) {
9+
ExtractMethodArgProjection(final ConstantDesc type, final int index) {
1010
super(type);
1111
this.index = index;
1212
}

src/main/java/de/mirkosertic/metair/ir/GetField.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ public class GetField extends Value {
1010
GetField(final ClassDesc owner, final ClassDesc fieldType, final String fieldName, final Value source) {
1111
super(fieldType);
1212

13-
if (source.type.isPrimitive() || source.type.isArray()) {
13+
if (source.isPrimitive() || source.isArray()) {
1414
illegalArgument("Cannot get field " + fieldName + " from non object source " + TypeUtils.toString(source.type));
1515
}
1616

src/main/java/de/mirkosertic/metair/ir/Invocation.java renamed to src/main/java/de/mirkosertic/metair/ir/Invoke.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
import java.lang.constant.MethodTypeDesc;
55
import java.util.List;
66

7-
public abstract class Invocation extends Value {
7+
public abstract class Invoke extends Value {
88

99
public final ClassDesc ownerType;
1010
public final Value target;
1111
public final String name;
1212
public final MethodTypeDesc typeDesc;
1313

14-
Invocation(final ClassDesc ownerType, final Value target, final String name, final MethodTypeDesc methodTypeDesc, final List<Value> arguments) {
14+
Invoke(final ClassDesc ownerType, final Value target, final String name, final MethodTypeDesc methodTypeDesc, final List<Value> arguments) {
1515
super(TypeUtils.jvmInternalTypeOf(methodTypeDesc.returnType()));
1616

17-
if (target.type.isPrimitive()) {
17+
if (target.isPrimitive()) {
1818
illegalArgument("Cannot invoke a method on a primitive value");
1919
}
2020

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package de.mirkosertic.metair.ir;
2+
3+
import java.lang.constant.ClassDesc;
4+
import java.lang.constant.MethodTypeDesc;
5+
import java.util.List;
6+
7+
public class InvokeDynamic extends Invoke {
8+
9+
public InvokeDynamic(final ClassDesc ownerType, final Value target, final String name, final MethodTypeDesc methodTypeDesc, final List<Value> arguments) {
10+
super(ownerType, target, name, methodTypeDesc, arguments);
11+
}
12+
13+
@Override
14+
public String debugDescription() {
15+
return "Invoke dynamic " + name + " : " + TypeUtils.toString(typeDesc);
16+
}
17+
18+
}

0 commit comments

Comments
 (0)