Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm target architecture for native image #3391

Open
jespertheend opened this issue May 2, 2021 · 48 comments
Open

Wasm target architecture for native image #3391

jespertheend opened this issue May 2, 2021 · 48 comments
Assignees
Labels

Comments

@jespertheend
Copy link

Feature request

Is your feature request related to a problem? Please describe.
I'm trying to port closure compiler to wasm so that it can run from within a browser.

Describe the solution you'd like.
Closure compiler already has build support for native image. So I was hoping to be able to use the LLVM backend but it seems like adding a new target architecture is a lot more work than I had expected.

Describe who do you think will benefit the most.
Anyone using GraalVM to build native image versions of their app would benefit from this, as they can now port their application to the web easily. Java developers who want to write a new application from the web could also benefit from this, they can now start developing in a language that they are already familiar with.

Describe alternatives you've considered.
I have tried the following alternatives:

  • CheerjP, works and runs closure compiler in a browser successfully, but the runtime is rather bulky, which needs to be downloaded first before you can run jar files. I'm also not sure about the performance. Wasm could be faster. Though I don't have any evidence to back this up.
  • TeaVM, could work as well. Though I haven't tried this yet to be honest. Their docs seem a bit daunting.
  • JWebAssembly might work but it is currently not production ready and still missing some crucial features.
  • Bytecoder doesn't seem to work for my use case since it doesn't support reflection. Something that closure compiler depends on.

Additional context.
The links in LLVM Backend for Native Image seem useful for implementing a new target.

Express whether you'd like to help contributing this feature
I'd love to, though if this feature request requires a similar change to the changes in [AArch64][Statepoints] Statepoint support for AArch64., I don't think I'm the suitable person to do this. I was hoping it would only require a few flags to be set on llvm but it seems like that's not the case.

@munishchouhan
Copy link
Contributor

@jespertheend thanks for the feature request, we are constantly adding new support to native-image and if we find it valuable to the community then surely we will add it in our future releases.

@munishchouhan
Copy link
Contributor

@christianwimmer please advise

@christianwimmer
Copy link

We have thought about a WASM backend, but it is not on our list of features to implement in the near future.
One of the biggest problems is the missing GC support in WASM: neither the GC of the underlying WASM/JS VM is exposed, nor stack walking is possible to include the existing SVM GC.

@munishchouhan munishchouhan removed their assignment May 5, 2021
@jespertheend
Copy link
Author

Ah yeah makes sense. Thanks for the info!
Would the wasm gc proposal make this any easier?

@christianwimmer
Copy link

christianwimmer commented May 6, 2021

Would the wasm gc proposal make this any easier?

Yes, once WASM has a proper GC interface things are getting much more feasible.

@jespertheend
Copy link
Author

Ah cool! I stay on the lookout for that then. Thanks for the info.

@shafqatevo
Copy link

Hi, now that there's an experimental WASI SDK for .net, can't such techniques be used to work around current Wasm limitations to run Substrate VM on Wasm?

Ref:
https://www.fermyon.com/blog/dotnet-wasi

https://github.com/SteveSandersonMS/dotnet-wasi-sdk

https://www.youtube.com/watch?v=A0vz_BWxIMc

@jimmywarting
Copy link

Don't seem to be the only one wanting to port closure compiler to wasm 😉
subscribing to this issue.

ping me @jespertheend if you ever release a wasm version of closure compiler :)

@jespertheend
Copy link
Author

@jimmywarting I'm actually about to ditch closure compiler in favour of terser to be honest. From my limited testing, builds seem to be slightly larger, but that seems worth it considering that it can run in a browser and generally seems to have less complexity.
You might have some luck with https://github.com/mirkosertic/Bytecoder but some features seem to still be missing for it to successfully build closure compiler to wasm.

@sdeleuze
Copy link
Collaborator

sdeleuze commented Aug 9, 2022

@christianwimmer Potentially interesting related links:

@VitGottwald
Copy link

Another tool in this area is bck2brwsr.

@mirkosertic
Copy link

Hi!

Author of https://github.com/mirkosertic/Bytecoder here. I can confirm that native garbage collection support is an issue in WebAssembly. The current Wasm GC proposal is in "proposed" status, as seen here: https://chromestatus.com/feature/6062715726462976. However, Google's J2CL Wasm backend seems to rely on this proposal, so I am really not sure when we can expect the final release and support in Chromium at least. Till this point, every Wasm backend for JVM bytecode needs to provide its own implementation for garbage collection. And implementing a fast and reliable garbage collector can be really tricky, and it can become a nightmare and impossible if you want to prevent stop-the-world during GC runs in a Wasm in a single threaded environment. Maybe we can get around that with reference counting, but performance is a very important part of it. Good escape analysis will remove some of the heap allocations, but in most real life applications a lot of stack allocation will remain.

But when the time comes and the Wasm GC proposal is final, it would be good to know what might be a feasible way to use the Graal native image compiler with Wasm. The LLVM backend path might work, but it is for sure not the fastest way. So what I am searching is a kind of documentation about how to provide a custom backend to Graal, or a kind of "embedded" API to run Graal, retrieve the IR (Graphs) and use them for a custom backend for code generation. Something that can be completely based on JVM, without further toolchains like LLVM and co.

@sdeleuze
Copy link
Collaborator

sdeleuze commented Jan 2, 2023

GC proposal made a lot of progresses in 2022 and moved to phase 3. We can't be sure when it will move to phase 4 but could be possible in 2023.

Implementations in other browsers has started:

@MTyson
Copy link

MTyson commented Mar 16, 2023

Hello, I'm writing an article for InfoWorld about Java and WASM. native-image --features=wasm sure would be nice. Could anyone comment on the status or any thoughts?

@tenaf0
Copy link

tenaf0 commented Nov 20, 2023

There has been quite a lot of movement around the WASM GC implementation, and it is available by default on chrome now, see https://developer.chrome.com/blog/wasmgc/

It might make sense to re-alive this issue.

@Martin1994
Copy link

Why a Java AOT solution has to rely on the GC implementation of WASM? A Java GC should be runnable on WASM with low level memory management API, and on the other side using WASM's GC will most likely lose the GC related APIs on Java side.

@tenaf0
Copy link

tenaf0 commented Nov 20, 2023

@Martin1994 From the article:

The C and Rust binaries could be anywhere from 6.1 K to 9.6 K depending on the various compiler flags, while the Java version is much smaller at only 2.3 K!

Compare it to the size of a C# application compiled to WASM, which is on the MB range, due to in part to having to also download on every site a complete GC/runtime implementation.

Given that Java can already be compiled to WASM (closure compiler, teawm), I believe that the WASM GC proposal’s API is more than fit for Java’s use case, and there are many advantages to using Graal, like polyglottism, size reduction (due to the closed world assumption, it can remove a bunch of classes that are never accessed), etc.

@sgammon
Copy link

sgammon commented Nov 20, 2023

In any case, this issue deserves a fresh look, because it opens GVM binaries up to new deployment targets, regardless of GC

(Consider users of --gc=epsilon, for example)

GC being shipped in several popular engines is a signal that WASM in general is maturing and stabilizing.

@boonyasukd
Copy link

FYI, Firefox 120 now enables Wasm GC by default (it was hidden under a flag for quite some time). I'd say the browser side is quite ready now. Kotlin team has been demoing/optimizing their work on Wasm GC since march, it'd be great if Graal supports it also.

https://www.mozilla.org/en-US/firefox/120.0/releasenotes/
https://twitter.com/bashorov/status/1716891482487988630

@ericvergnaud
Copy link

WASM GC is available in V8 (Chrome, Deno and soon Node).
It'd be very disappointing to not see it rapidly coming to GraalVM

@a-cosmic-jaw
Copy link

Hello? Where are we on this?

@axel22
Copy link
Member

axel22 commented May 6, 2024

We are working on and have an in-progress implementation that outputs Wasm (with the WasmGC spec).

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend.
What sort of deployments scenarios do you foresee or have need for (e.g. do you need to target browser applications, or run Wasm modules in standalone mode with WASI)?

Thank you!

@gocursor
Copy link

gocursor commented May 6, 2024

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend. What sort of deployments scenarios do you foresee or have need for (e.g. do you need to target browser applications, or run Wasm modules in standalone mode with WASI)?

Primarily browser apps (to share the code between frontend and backend and to leverage the existing Java skills).

@CedNaru
Copy link

CedNaru commented May 6, 2024

Hello, I am one of the maintainers of the Kotlin-Java bindings for the Godot game engine (https://github.com/utopia-rise/godot-kotlin-jvm).

Godot supports exports for the main 3 desktop OS, Android, iOS and wasm. Wasm is currently the only export we don't support because we lack a simple way to run a JRE inside the browser.
We already support the use of native images (our only way to run it on iOS currently) and a wasm target would be welcomed to complete our Godot support.

An alternative would be to use Kotlin/Native and Kotlin/Wasm instead of native images, but Godot being a C++ engine, we rely heavily on interop. Using different backends for Kotlin would require us to implement a specific interop layer for each of them. It would be much simpler for us if we could just keep using a regular JRE + JNI context for all of them.

@agarciadom
Copy link

I am one of the developers of the Eclipse Epsilon project. We provide a family of mini-languages for managing object-oriented system models (e.g. validating them, generating code from them, and so on). They are all interpreted languages, running on top of Java.

We started as being Eclipse-centric (it was the shiny new thing back in the mid 00s), but we are seeing more and more people interested in doing modelling from their browsers (e.g. from low-code development platforms). In fact, to make it easier for people to try out our languages, we've created a web-based Playground for the Epsilon languages.

The annoying part is that, since we can't run Java code on the browser, executing the code in the Playground involves spinning up a Google Cloud Function that runs the script, which is 1) costly and 2) slow. We'd very much like to use something like the Graal integration in Micronaut to package up our interpreter as a module that we could use from the Playground.

It'd also open other opportunities - for instance, we have the start of a language server for Epsilon, which is also written in Java. With a WasmGC export, we could look into running the language server from Node.js, which is one of the default runtimes supported by VS Code.

@lemmy
Copy link

lemmy commented May 7, 2024

The annoying part is that, since we can't run Java code on the browser, executing the code in the Playground involves spinning up a Google Cloud Function that runs the script, which is 1) costly and 2) slow. We'd very much like to use something like the Graal integration in Micronaut to package up our interpreter as a module that we could use from the Playground

https://github.com/tlaplus/tlaplus has a pretty similar use case.

@gkresic
Copy link

gkresic commented May 8, 2024

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend.

Running Java code in browser environments would be our primary target, but WASI (although still in its infancy) shouldn't be ignored too. However, important feature in both cases would be as-good-as-possible support for integrations with JavaScript (in browser) and other WASM modules (especially ones written in languages other than Java).

@simlei
Copy link

simlei commented May 8, 2024 via email

@lisonge
Copy link

lisonge commented May 27, 2024

It would be really helpful for us if people could explain their use-cases for having a WasmGC backend.

I need to run Java regular expressions in the browser with the same behavior as on the JVM. However, the native JavaScript RegExp and Java's Pattern exhibit inconsistent behavior. For example, JavaScript does not allow embedded flags in regular expressions, whereas Java does.

It seems the only solution is to compile Java's Pattern to WebAssembly (wasm) for JavaScript to call.

My current solution is to use Kotlin Multiplatform to compile Kotlin's kotlin.text.Regex to wasm for JavaScript to call.

https://github.com/gkd-kit/gkd/blob/v1.7.3/wasm_matches/src/commonMain/kotlin/li/songe/matches/toMatches.kt

https://github.com/gkd-kit/inspect/blob/f8b58ae6c34cf9559f148b566ddaadb0d3138cd4/src/utils/selector.ts#L14

if Graal could support compiling Java to WebAssembly (wasm) for JavaScript to call, then more Java libraries could be run directly in the browser, eliminating the need to manually re-implement them in JavaScript

For example, I recently wanted to port the functionality of converting SVG to XML from Android Studio to the browser. The source code is available at Svg2Vector.java. If these Java code could be directly compiled to WebAssembly (wasm), it would eliminate the need to manually re-implement it in JavaScript.

@bashor
Copy link

bashor commented May 27, 2024

@lisonge, you can convert Svg2Vector.java to Kotlin 🫣 and continue using Kotlin Multiplatform 😉

@lisonge
Copy link

lisonge commented May 28, 2024

@lisonge, you can convert Svg2Vector.java to Kotlin 🫣 and continue using Kotlin Multiplatform 😉

@bashor The third-party library java.awt.* that it uses cannot be used with Kotlin Multiplatform

@sgammon
Copy link

sgammon commented May 28, 2024

@axel22 our use case is mostly server side, similar to Node. we want to support WASI as a server side target, especially on platforms like Cloudflare Workers.

many isolate-based hosting platforms can only accept WASM or JavaScript. compiling to WASM is therefore a fundamental need unless V8 begins accepting other binary types (unlikely).

this would also lower the cost floor for hosting a GraalVM application significantly. because WASM is not supported yet, one must resort to a container or a full VM, or even bare metal, all of which have much higher cost floors than isolate-based hosting.

@rdobrik
Copy link

rdobrik commented Jun 4, 2024

We are working on Java stack for Internet Computer blockchain platform https://internetcomputer.org/. Currently developing Java Agent libraries but there is a demand for Java based backend smart contracts (canisters). Internet Computer backend is based on WASM and currently supports different languages like Rust, C++, Python and Javascript. While IO access will be quite restrictive, we will need to support Java reflections and annotations to be able serialize and deserialize Java types (like Jackson or Gson) to internal ICP data format. We already have code for that. Also support libraries like Bouncy Castle for encryption and decryption.

@nilslice
Copy link

This is really exciting! We'd love to be able to support a Java PDK for Extism, which would mean supporting a Java library that calls some external functions (some static, like wasip1), and some created by a Host environment, linking them dynamically.

Extism environments are embedded within other applications including things that run on the server, browser, IoT, and mobile.

@ningpengtao-coder
Copy link

I want to run my own swing application on wasm.

@ceisserer
Copy link

Is there any new regarding this topic? To me it seems all the required infrastructure is there (GC Proposal, Reference Types, Atomics).
Regarding the use-case I guess I am not the only one with plenty of "legacy" Java desktop code which just needs a proper migration path to move on from JSE8.

@wolonge95
Copy link

Target browser.

@odenix
Copy link

odenix commented Oct 23, 2024

My use case is to run the Pkl Truffle language in the browser (for educational purposes).

@Sintrastes
Copy link

Very interested in WASI / WIT support to be able have the graal ecosystem target a custom plugin ecosystem.

Basically the goal is to allow for third-parties to write a plugin in whatever language they want, so having the graal ecosystem as an option would be a huge win.

@nilslice
Copy link

@Sintrastes - curious if you've come across https://extism.org, which makes all of that possible today across many more languages than WIT can generate.

we don't have support for GraalWasm yet, but would be open to collaborating!

we also have a similar binding generator toolchain with support for Go, Rust, TypeScript, Python, C#, C++ and Zig (with more coming!). we release all of this freely and under permissive licenses, learn more here: https://docs.xtp.dylibso.com/docs/concepts/xtp-schema

@Sintrastes
Copy link

@nilslice - Interesting! No, I was not familiar with this previously.

In terms of the IDL, are there plans to add support for things like sum types, like in WIT?

@nilslice
Copy link

@Sintrastes - great question, and probably not in the near term, but it's not out of the question.

XTP schema takes a very pragmatic approach to try and bring wasm to every app; vs try to make all apps wasm. So we take lots of care to not introduce features that are incompatible or create a non-idiomatic mess of generated code.

Sum types could be done, but they don't exist in all the languages we support - so we'd have to hand over a wonky Frankenstein combination of structs/methods/enums/states etc. to our users and we have a hard time shipping things that don't work great.

We also stick closely to OpenAPI spec, given that a local in-process plugin is basically just a bi-directional API call, and there's a LOT of OpenAPI based systems out there.

I don't mean to take over the discussion here, so please feel free to join us on Discord: https://extism.org/discord

@ningpengtao-coder
Copy link

ningpengtao-coder commented Nov 22, 2024

https://github.com/stackblitz/bolt.new has opened a low-code tool for using llm.
Using stackblitz's private webcontainer technology, it simulates the nodejs environment and runtime in the browser to support running front-end projects in the browser.
bolt-new fork: https://github.com/coleam00/bolt.new-any-llm plans to use open source components instead of webcontainer.
Open source components:
https://github.com/wasmerio/wasmer
https://github.com/Sandpack/nodebox-runtime
https://github.com/leaningtech/webvm

issue:
stackblitz-labs/bolt.diy#229

can Graal introduce more runtime support?, such as GraalPython, GraalJS, Espresso (Java), etc., and convert these runtimes into wasm.

My personal experience using graal:
I use graal to package swing programs into native and run them on desktop and mobile. But compared to browsers, it is very difficult to distribute programs on desktop and mobile.
From practical experience, small programs, PWA and web are commonly used now, which are easier to distribute. These are areas where wasm is more likely to exert its strength.

And now is the era of AI, and entrepreneurial technology selection is more inclined to languages ​​such as JS and Python. If wasm can be supported, Graal can be more organically combined with AI, and Graal will have a wider range of usage scenarios.

@Frontrider
Copy link

And now is the era of AI, and entrepreneurial technology selection is more inclined to languages ​​such as JS and Python. If wasm can be supported, Graal can be more organically combined with AI, and Graal will have a wider range of usage scenarios.

Graal can get your jvm code to interact with python code and libraries directly. That is not the problem, that topic is not really a factor.

A more important entrepreneurial tech is that webassembly is cloud native, you can run it with docker directly.

@ningpengtao-coder
Copy link

@Frontrider This only satisfies running Python on the Java backend and running WASM in container runtimes (WasmEdge). It cannot run in browsers.

The following is a commercial product that can run Java applications in browsers, including Swing, Applet, and extensive framework support: https://cheerpj.com/

@ceisserer
Copy link

Cheerpj however is rather slow (while it can run Swing technically, "real" Swing applications work but are no fun to use). Furthermore they have a rather special view on OpenJDKs GPL+linking exception - I once asked for their WASM platform peer bindings (file/network/awt/java2d/etc) and the declined stating GPL+linking covers this.

@ningpengtao-coder
Copy link

@ceisserer Thank you for your response. It's possible that CheerpJ does not support WebGPU very well? GraalVM's native-image compiles Java code into native code through the compiler toolchain, and it can also support WASM through the compiler toolchain. I am very hopeful that Java GUI technology can be brought back to the browser through GraalVM.

@Frontrider
Copy link

Frontrider commented Dec 21, 2024

@ceisserer Thank you for your response. It's possible that CheerpJ does not support WebGPU very well? GraalVM's native-image compiles Java code into native code through the compiler toolchain, and it can also support WASM through the compiler toolchain. I am very hopeful that Java GUI technology can be brought back to the browser through GraalVM.

This is already proven to be feasible, as this is basically what Kotlin Compose does for the web. Except it uses their own compiler.

I'm also reading some articles on SPA-s, and some of the things those are used for are literally better to do even with swing. When you have a lot of data to display, and the dom tree becomes way too convoluted.
The point is that it will come back as soon as the tech is free, and usable.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests