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