www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - D and WebAssembly (Wasm)

reply Kenneth Dallmann <fake 123.con> writes:
   Greetings!

    Many people in the development community are very excited about
WebAssembly, because it allows the browser to interpret more 
robust
languages than JS.

    Rumor has it that D can compile to Wasm, but only in the 
"BetterC"
subset.

    LLVM can compile to Wasm, but unfortunately it may not support
systems IO calls because of the lack of operating system access.
Emscripten is a compiler that can transform C into something that
can run on Wasm without holes in the Standard Library.  It does
this by simulating an operating system, which adds overhead to the
runtime, but allows a full range of C to be used, to my 
understanding.

With D not being able to be run on Wasm in a meaning way: Why 
can't
we just compile D code to C, as a compiler output, and then run 
that
through Emscripten?
Sep 13
next sibling parent reply jfondren <julian.fondren gmail.com> writes:
On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
wrote:
 Why can't
 we just compile D code to C, as a compiler output, and then run 
 that
 through Emscripten?
The immediate problem is that a D->C compiler does not exist.
Sep 13
next sibling parent jfondren <julian.fondren gmail.com> writes:
On Monday, 13 September 2021 at 16:29:45 UTC, jfondren wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
 Why can't
 we just compile D code to C, as a compiler output, and then 
 run that
 through Emscripten?
The immediate problem is that a D->C compiler does not exist.
https://theartofmachinery.com/2018/12/20/emscripten_d.html explains that C isn't necessary:
Emscripten is a toolchain designed for C/C++, but the C/C++ part 
is just a frontend. The toolchain actually compiles LLVM 
intermediate representation (IR). You can generate LLVM IR 
bitcode from D using LDC, so it should be possible to feed that 
through Emscripten and run D in a browser, just like C/C++.
Sep 13
prev sibling parent reply Kenneth Dallmann <fake 123.con> writes:
On Monday, 13 September 2021 at 16:29:45 UTC, jfondren wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
 Why can't
 we just compile D code to C, as a compiler output, and then 
 run that
 through Emscripten?
The immediate problem is that a D->C compiler does not exist.
I read somewhere that BetterC can though, and maybe that's how it works. Although, with the LLVM you can compile it to Wasm, it just won't have the standard library, a technical nightmare. Maybe a D to C compiler would be a good project, to increase the portability of D.
Sep 13
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Monday, 13 September 2021 at 16:36:10 UTC, Kenneth Dallmann 
wrote:
 On Monday, 13 September 2021 at 16:29:45 UTC, jfondren wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
 Why can't
 we just compile D code to C, as a compiler output, and then 
 run that
 through Emscripten?
The immediate problem is that a D->C compiler does not exist.
I read somewhere that BetterC can though, and maybe that's how it works. Although, with the LLVM you can compile it to Wasm, it just won't have the standard library, a technical nightmare. Maybe a D to C compiler would be a good project, to increase the portability of D.
Would be a cool project
Sep 14
prev sibling next sibling parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
wrote:
    Rumor has it that D can compile to Wasm, but only in the 
 "BetterC" subset.
See some of my little demos here: http://webassembly.arsdnet.net/ a blog post about it http://dpldocs.info/this-week-in-d/Blog.Posted_2020_08_10.html and some source for the support code http://github.com/adamdruppe/webassembly/ the approach I took is a miniature custom runtime but there's also the possibility of a druntime port to the wasi emscripten uses https://github.com/skoppe/druntime/tree/wasm though none of these are complete. Anyway, the point of my little demo is in 50 KB of webasm I had my basic game demos running in the browser. I did partial source ports that just call out to javascript instead of relying on a copied stdlib. Makes more sense that way to me and also produces smaller binaries.
Sep 13
parent Kenneth Dallmann <fake 123.con> writes:
On Monday, 13 September 2021 at 16:33:28 UTC, Adam D Ruppe wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
    Rumor has it that D can compile to Wasm, but only in the 
 "BetterC" subset.
See some of my little demos here: http://webassembly.arsdnet.net/
How funny I was playing your tetris game earlier today. I found it in a blog post on the same topic.
Sep 13
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
wrote:
 With D not being able to be run on Wasm in a meaning way: Why 
 can't
 we just compile D code to C, as a compiler output, and then run 
 that
 through Emscripten?
The [D language runtime][1] uses inline assembly for some low-level features (e.g., threads), and therefore cannot be compiled to C. Emscripten itself has [similar limitations.][2] [1]: https://github.com/dlang/druntime/ [2]: https://emscripten.org/docs/porting/guidelines/portability_guidelines.html#code-that-cannot-be-compiled
Sep 13
next sibling parent Kenneth Dallmann <fake 123.con> writes:
On Monday, 13 September 2021 at 16:36:28 UTC, Paul Backus wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
 With D not being able to be run on Wasm in a meaning way: Why 
 can't
 we just compile D code to C, as a compiler output, and then 
 run that
 through Emscripten?
The [D language runtime][1] uses inline assembly for some low-level features (e.g., threads), and therefore cannot be compiled to C. Emscripten itself has [similar limitations.][2] [1]: https://github.com/dlang/druntime/ [2]: https://emscripten.org/docs/porting/guidelines/portability_guidelines.html#code-that-cannot-be-compiled
Inline assembly is described here for the C language. https://en.cppreference.com/w/c/language/asm#:~:text=Inline%20assembly%20(typically%20introduced%20by,as%20an%20extension%20in%20C.
Sep 13
prev sibling next sibling parent Kenneth Dallmann <fake 123.con> writes:
On Monday, 13 September 2021 at 16:36:28 UTC, Paul Backus wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
 With D not being able to be run on Wasm in a meaning way: Why 
 can't
 we just compile D code to C, as a compiler output, and then 
 run that
 through Emscripten?
The [D language runtime][1] uses inline assembly for some low-level features (e.g., threads), and therefore cannot be compiled to C. Emscripten itself has [similar limitations.][2] [1]: https://github.com/dlang/druntime/ [2]: https://emscripten.org/docs/porting/guidelines/portability_guidelines.html#code-that-cannot-be-compiled
My bad, you got that correct. I guess someone would have to write a compiler/RTL specifically for D to run it on Wasm. I noticed that threads is one feature disabled in BetterC, and maybe that's why it has been ported to Wasm.
Sep 13
prev sibling parent Denis Feklushkin <denis.feklushin gmail.com> writes:
On Monday, 13 September 2021 at 16:36:28 UTC, Paul Backus wrote:
 On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
 wrote:
 With D not being able to be run on Wasm in a meaning way: Why 
 can't
 we just compile D code to C, as a compiler output, and then 
 run that
 through Emscripten?
The [D language runtime][1] uses inline assembly for some low-level features (e.g., threads), and therefore cannot be compiled to C. Emscripten itself has [similar limitations.][2]
Time to remind everyone about my project: https://github.com/denizzzka/d_c_arm_test It just allows to take these things into a small "backend": https://github.com/denizzzka/d_c_arm_test/tree/master/d/freertos_druntime_backend/external It is possible to write same backend for webasm or any other platform. (But now there is a tiny problem with the Meson, which does not allow to package arbitrary dub and any others repositories into Meson. PR is waiting for approval.)
Sep 15
prev sibling next sibling parent reply Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
wrote:
   Greetings!

    Many people in the development community are very excited 
 about
 WebAssembly, because it allows the browser to interpret more 
 robust
 languages than JS.

    Rumor has it that D can compile to Wasm, but only in the 
 "BetterC"
 subset.

    LLVM can compile to Wasm, but unfortunately it may not 
 support
 systems IO calls because of the lack of operating system access.
 Emscripten is a compiler that can transform C into something 
 that
 can run on Wasm without holes in the Standard Library.  It does
 this by simulating an operating system, which adds overhead to 
 the
 runtime, but allows a full range of C to be used, to my 
 understanding.

 With D not being able to be run on Wasm in a meaning way: Why 
 can't
 we just compile D code to C, as a compiler output, and then run 
 that
 through Emscripten?
You don't need to compile d code to c. You can use d code with emscripten. Sebastiaan Koppe was working on druntime[1] to make it possible to use it with webassembly. Dunno its current status. Here is also my d game using wasm. It even links with c libraries compiled with emscripten. https://aferust.github.io/drawee/ https://github.com/aferust/drawee [1]: https://github.com/skoppe/druntime/tree/wasm
Sep 13
next sibling parent reply Kenneth Dallmann <fake 123.con> writes:
On Monday, 13 September 2021 at 17:19:23 UTC, Ferhat Kurtulmuş 
wrote:

 You don't need to compile d code to c. You can use d code with 
 emscripten. Sebastiaan Koppe was working on druntime[1] to make 
 it possible to use it with webassembly. Dunno its current 
 status. Here is also my d game using wasm. It even links with c 
 libraries compiled with emscripten.

 https://aferust.github.io/drawee/
 https://github.com/aferust/drawee

 [1]: https://github.com/skoppe/druntime/tree/wasm
Yeah, thanks for answering! Sounds like you guys got it figured out. You can just use the LLVM compiler to compile to LLVM intermediate code and then feed that directly into Emscripten. I wasn't able to find this info online, specifically. If this is true then D is 100% fully executable on via Emscripten Wasm.
Sep 13
parent Dukc <ajieskola gmail.com> writes:
On Monday, 13 September 2021 at 18:11:22 UTC, Kenneth Dallmann 
wrote:
 Yeah, thanks for answering! Sounds like you guys got it figured 
 out. You can just use the LLVM compiler to compile to LLVM 
 intermediate code and then feed that directly into Emscripten.

   I wasn't able to find this info online, specifically. If this 
 is true then D is
 100% fully executable on via Emscripten Wasm.
You don't need Emscripten at all. LDC can target WASM directly.
Sep 13
prev sibling parent reply Sebastiaan Koppe <mail skoppe.eu> writes:
On Monday, 13 September 2021 at 17:19:23 UTC, Ferhat Kurtulmuş 
wrote:
 You don't need to compile d code to c. You can use d code with 
 emscripten. Sebastiaan Koppe was working on druntime[1] to make 
 it possible to use it with webassembly. Dunno its current 
 status. Here is also my d game using wasm. It even links with c 
 libraries compiled with emscripten.

 https://aferust.github.io/drawee/
 https://github.com/aferust/drawee

 [1]: https://github.com/skoppe/druntime/tree/wasm
Yes, just yesterday I started to get back to that work again. I am currently updating to latest ldc and wasi sdk. Couple of months ago all druntime/phobos tests were passing and I hope to get there again (well, all except thread/fibers/exceptions, since they aren't suported). You can already use the forks to build ldc phobos/druntime libs for use in wasm. It is a bit cumbersome to setup but it works. If that isn't your cup of tea - won't blame you - you'll have to stick to adam's custom runtime or plain betterC, which also works fine. Especially since spasm has bindings to all web api's. examples: https://skoppe.github.io/spasm/examples/todo-mvc/ https://skoppe.github.io/spasm/examples/underrun/ https://skoppe.github.io/spasm-imgui/
Sep 13
parent Ferhat =?UTF-8?B?S3VydHVsbXXFnw==?= <aferust gmail.com> writes:
On Monday, 13 September 2021 at 21:14:16 UTC, Sebastiaan Koppe 
wrote:
 On Monday, 13 September 2021 at 17:19:23 UTC, Ferhat Kurtulmuş 
 wrote:
 [...]
Yes, just yesterday I started to get back to that work again. I am currently updating to latest ldc and wasi sdk. Couple of months ago all druntime/phobos tests were passing and I hope to get there again (well, all except thread/fibers/exceptions, since they aren't suported). You can already use the forks to build ldc phobos/druntime libs for use in wasm. It is a bit cumbersome to setup but it works. If that isn't your cup of tea - won't blame you - you'll have to stick to adam's custom runtime or plain betterC, which also works fine. Especially since spasm has bindings to all web api's. examples: https://skoppe.github.io/spasm/examples/todo-mvc/ https://skoppe.github.io/spasm/examples/underrun/ https://skoppe.github.io/spasm-imgui/
Thank you Sebastiaan. Latest wasi support sounds awesome. If I remember correctly, the supported version was 8. It is nice to know you keep working on it.
Sep 13
prev sibling parent Dukc <ajieskola gmail.com> writes:
On Monday, 13 September 2021 at 16:19:31 UTC, Kenneth Dallmann 
wrote:
    Rumor has it that D can compile to Wasm, but only in the 
 "BetterC"
 subset.
True. Or alternatively, you probably can do it by simply not using the unported DRuntime parts, and defining a few stub functions for those runtime calls that remain in the binary anyway.
    LLVM can compile to Wasm, but unfortunately it may not 
 support
 systems IO calls because of the lack of operating system access.
You're supposed to create the system hooks for WASM yourself, or use a library for doing that. https://code.dlang.org/packages/spasm should be your first stop when using D. I think WASM is designed so you can run code unprivileged code in it, as opposed to asm.js which always has full access to it's environment.
 Emscripten is a compiler that can transform C into something 
 that
 can run on Wasm without holes in the Standard Library.  It does
 this by simulating an operating system, which adds overhead to 
 the
 runtime, but allows a full range of C to be used, to my 
 understanding.
You can compile D to asm.js using the Emscripten backend, and then call the C API. No need for a C transpilation. However, I prefer WASM myself. It does not require a massive framework like Emscripten, and also it felt less buggy. And you can use Spasm with it.
Sep 13