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