Initial Prototype Experimentation
Ethan McCue
ethan at mccue.dev
Wed Jan 31 15:43:52 UTC 2024
Hi all,
I understand this is extremely early, but I started trying to experiment
with the prototype API yesterday. I feel like there are some core concepts
that I am not understanding.
I was trying to make a basic Java -> JS compiler. The idea is that if you
stick to a set of special classes and initialize them with constants, there
would be a mechanical translation to equivalent JS.
final class OnlyAvailableInBrowser extends RuntimeException {
}
public final class JsConsole {
private JsConsole() {}
public static void log(JsAny o) {
throw new OnlyAvailableInBrowser();
}
}
public sealed abstract class JsAny permits JsString {
}
public final class JsString extends JsAny {
private JsString() {}
public static JsString of(String s) {
throw new OnlyAvailableInBrowser();
}
}
So if there is a method like this
@CodeReflection
public static void f() {
var s = JsString.of("abc");
JsConsole.log(s);
}
Then I want to get at the fact that the string constant "abc" is passed to
JsString#of, that the result of that gets assigned to a variable, and that
that variable gets passed to JsConsole#log
Looking at the model and the body of the model doesn't give me many clues
public static void main(String[] args) throws NoSuchMethodException {
var model = Main.class.getMethod("f")
.getCodeModel()
.orElseThrow();
System.out.println(model);
System.out.println(model.body());
java.lang.reflect.code.op.CoreOps$FuncOp at 63440df3
java.lang.reflect.code.Body at 6121c9d6
Looking at the operations in the body gets me closer
model.body().entryBlock().ops().forEach(System.out::println);
java.lang.reflect.code.op.CoreOps$ConstantOp at 1060b431
java.lang.reflect.code.op.CoreOps$InvokeOp at 612679d6
java.lang.reflect.code.op.CoreOps$VarOp at 11758f2a
java.lang.reflect.code.op.CoreOps$VarAccessOp$VarLoadOp at e720b71
java.lang.reflect.code.op.CoreOps$InvokeOp at 1b26f7b2
java.lang.reflect.code.op.CoreOps$ReturnOp at 491cc5c9
But it's unclear, to me, how to tie the invoke op to the constant op. The
only unique method on InvokeOp is invokeDescriptor which doesn't seem right.
.operands() seems appropriate, but that has a list of
[java.lang.reflect.code.Op$Result at 6a1aab78]. Looking at that class I see an
op method
var invokeOp = (CoreOps.InvokeOp) model
.body()
.entryBlock()
.ops()
.get(1);
System.out.println(((Op.Result) invokeOp.operands().get(0)).op());
Which does get me a constant op, but I don't quite understand how to relate
that constant op to the op in the list of ops. Or, put another way, I don't
understand how to traverse the model properly.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/babylon-dev/attachments/20240131/6a614c3f/attachment-0001.htm>
More information about the babylon-dev
mailing list