Skip to content

WASM research

Dang Mai edited this page Oct 7, 2024 · 10 revisions

This page layouts my research about compiling jorje to WASM or Javascript to enable better performance for Prettier Apex.

For a lot of these methods, I use a simplied DirectApex.cls next to Apex.cls with fewer integration, so that I can rule out all unnecessary dependencies.

package net.dangmai.serializer;

import apex.jorje.data.Locations;
import apex.jorje.semantic.compiler.SourceFile;
import apex.jorje.semantic.compiler.parser.ParserEngine;
import apex.jorje.semantic.compiler.parser.ParserOutput;
import java.io.IOException;

public class DirectApex {

  public static void getAST(Boolean anonymous) throws IOException {
    String sourceCode = "public class Test { }";
    SourceFile sourceFile = SourceFile.builder().setBody(sourceCode).build();
    ParserEngine engine;
    if (anonymous) {
      engine = ParserEngine.get(ParserEngine.Type.ANONYMOUS);
    } else {
      engine = ParserEngine.get(ParserEngine.Type.NAMED);
    }
    Locations.useIndexFactory(); // without this, comments won't be retained correctly
    ParserOutput output = engine.parse(
      sourceFile,
      ParserEngine.HiddenTokenBehavior.COLLECT_COMMENTS
    );
  }

  public static void main(String[] args) throws IOException {
    getAST(false);
  }
}

Bytecoder

Links

Steps

cd packages/apex-ast-serializer/parser
wget https://repo.maven.apache.org/maven2/de/mirkosertic/bytecoder/bytecoder-cli/2024-05-10/bytecoder-cli-2024-05-10-executable.jar
mkdir bytecoder-output
pnpm nx run --skip-nx-cache apex-ast-serializer:build && java -jar bytecoder-cli-2024-05-10-executable.jar compile js -classpath=./build/classes/java/main,../libs/apex-jorje-lsp.jar,./build/libs/parser-1.0-SNAPSHOT.jar -mainclass=net.dangmai.serializer.DirectApex -builddirectory=./bytecoder-outpu

Findings

Bytecoder still lacks full coverage of JDK. I run into this issue: Caused by: java.lang.IllegalStateException: No such method : java/lang/Integer.highestOneBit(I)I. Attempts to patch this method into ByteCoder has not been successful. I've tried to add a custom TInteger.java with the missing method into the package package de.mirkosertic.bytecoder.classlib.java.lang but it doesn't seem to picked up.

J2CL

Links

Findings

  • Need actual source code to compile. Idea: we could use vineflower to decompile jorje to sources, then run it through J2CL.
  • After jumping through the hoops of decompiling + setting up Bazel, we are still running into errors with log
  • It looks like J2CL is still missing quite a few standard libraries. I tried removing as much dependencies as possible from jorje JAR file, but there are still a lot of errors left. Some modules jumped out at me right off the bat: java.time.*, java.text.* which are used by jorje.
  • List of supported modules are here: https://github.com/google/j2cl/tree/master/jre

GraalVM to WASM

Links

TeaVM

Links

Findings

  • After adding a bunch of stubs for classes/interfaces not implemented by TeaVM, I run into this one that I can't fix: teavm.log It's basically not letting me patch ClassLoader to support getPlatformClassLoader method.
  • It looks like TeaVM can't transpile the full Guava library, which jorje uses. See this issue: https://github.com/konsoletyper/teavm/issues/342
  • Apparently there's no way to add single missing methods to classlib based on this answer: https://groups.google.com/g/teavm/c/G2nY5Uv__Bw/m/gmgrl57fAAAJ (For individual method of a class there's no solution.)
  • Breakthrough! ESM JS has been exported.
Clone this wiki locally