Skip to content

Commit

Permalink
Basic Truffle DSL usage
Browse files Browse the repository at this point in the history
  • Loading branch information
steve-s committed May 12, 2022
1 parent 9d363f7 commit 7f4f999
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 29 deletions.
6 changes: 6 additions & 0 deletions pom.xml
Expand Up @@ -41,6 +41,12 @@
<version>4.13.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.graalvm.truffle</groupId>
<artifactId>truffle-dsl-processor</artifactId>
<version>${graalvm.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
95 changes: 72 additions & 23 deletions src/main/java/org/apidesign/demo/talk2compiler/Main.java
@@ -1,45 +1,94 @@
package org.apidesign.demo.talk2compiler;

import com.oracle.truffle.api.CallTarget;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.CompilerDirectives;
import com.oracle.truffle.api.Truffle;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.NodeChild;
import com.oracle.truffle.api.dsl.NodeChildren;
import com.oracle.truffle.api.dsl.Specialization;
import com.oracle.truffle.api.frame.VirtualFrame;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.nodes.RootNode;
import com.oracle.truffle.api.nodes.Node;
import com.oracle.truffle.api.profiles.BranchProfile;

public class Main extends RootNode {
static final Main MAIN = new Main();
static final Main MAIN;

static Plus newPlus(Compute l, Compute r) {
return MainFactory.PlusNodeGen.create(l, r);
}

static {
Compute p = newPlus(new Index(0),
newPlus(new Index(2), new Index(1))
);
MAIN = new Main(p);
}
static final CallTarget CODE = Truffle.getRuntime().createCallTarget(MAIN);

private Main() {
@Child private Compute program;

private Main(Compute program) {
super(null);
this.program = program;
}

public static void main(String... args) {
System.err.println(CODE.call((Object) new Number[] { 5, Math.PI, 11, 15 }));
}

@Override
public Object execute(VirtualFrame frame) {
final String name = (String) frame.getArguments()[0];
return formatGreeting("Hello from %s!", name);
public Object execute(VirtualFrame frame) {
return program.executeEval(frame);
}

@TruffleBoundary
private static String formatGreeting(String msg, String name) {
return String.format(msg, name);
public static abstract class Compute extends Node {
public abstract Object executeEval(VirtualFrame frame);
}

public static void main(String... args) {
String who = args.length > 0 ? args[0] : "unknown";
int cnt;
if (Boolean.getBoolean("noigv")) {
cnt = 1;
} else {
cnt = args.length > 1 ? Integer.parseInt(args[1]) : 10000000;
@NodeChildren({
@NodeChild(value = "left"),
@NodeChild(value = "right")})
public static abstract class Plus extends Compute {
@Specialization
Number doII(int left, int right) {
return left + right;
}

@Specialization
Number doDI(double left, int right) {
return left + right;
}
int print = 1;
for (int i = 1; i <= cnt; i++) {
final Object result = CODE.call(who);
if (i >= print) {
System.err.println("run #" + i + " result: " + result);
print *= 2;
}

@Specialization
Number doID(int left, double right) {
return left + right;
}

@Specialization
Number doDD(double left, double right) {
return left + right;
}

@Fallback
Object doFallback(Object leftValue, Object rightValue) {
CompilerDirectives.transferToInterpreter();
throw new IllegalStateException("Cannot + for " + leftValue + " and " + rightValue);
}
}

public static final class Index extends Compute {
private final int index;

public Index(int index) {
this.index = index;
}

@Override
public Number executeEval(VirtualFrame frame) {
return (Number) frame.getArguments()[index];
}
}
}
13 changes: 7 additions & 6 deletions src/test/java/org/apidesign/demo/talk2compiler/MainTest.java
Expand Up @@ -12,19 +12,20 @@ public void warmingUp() {
// Skip warmup if IGV dump isn't requested
count = 1;
} else {
count = 10000000;
count = 1000000000;
}
Number[] arr = { 7, 8, 9 };
for (int i = 0; i < count; i++) {
sayHelloTruffle();
eval(arr);
}
}

@Test
public void checkSayHello() {
Assert.assertEquals("Hello from Truffle!", sayHelloTruffle());
public void evalTest() {
Assert.assertEquals(16 + Math.PI, eval(new Number[] { 5, Math.PI, 11, 15 }));
}

private static Object sayHelloTruffle() {
return Main.CODE.call("Truffle");
private static Object eval(Number[] arr) {
return Main.CODE.call(arr);
}
}

0 comments on commit 7f4f999

Please sign in to comment.