Initial Prototype Experimentation

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Jan 31 15:50:06 UTC 2024


Hi Ethan,
to show the contents of a method body, it is recommended to use the 
Op::toText method. This converts the op in a representation that can be 
more easily understood by us humans.

I suggest you look there, and see if that helps understanding better how 
things are connected (it sure helped me a lot).

Cheers
Maurizio


On 31/01/2024 15:43, Ethan McCue wrote:
> 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/f0f99b89/attachment.htm>


More information about the babylon-dev mailing list