-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Crystal Compiler can't target asm.js #535
Comments
I tried fooling around a bit by compiling crystal against emscripten-fastcomp, but without much luck (it compiled, but it doesn't seem to have the target available). But even if we get past this point, in Crystal head pretty much every program depends on libevent, libpcl and libpcre, so these would need to be ported first anyway. |
You may use the |
I've made some progress fairly recently. _cat number.cr_ 1 _./bin/crystal build --mcpu asmjs --emit llvm-ir --verbose --single-module --prelude=empty number.cr_
_cat number.ll_ ; ModuleID = 'main_module'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx"
@ARGC_UNSAFE = global i32 0
@ARGV_UNSAFE = global i8** null
define internal i32 @__crystal_main(i32 %argc, i8** %argv) {
entry:
store i32 %argc, i32* @ARGC_UNSAFE
store i8** %argv, i8*** @ARGV_UNSAFE
ret i32 1
}
declare i32 @printf(i8*, ...)
; Function Attrs: uwtable
define i32 @main(i32 %argc, i8** %argv) #0 {
entry:
%0 = call i32 @__crystal_main(i32 %argc, i8** %argv)
ret i32 0
}
attributes #0 = { uwtable "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf"="true" } _emcc -o number.js -rdynamic number.ll_
_cat number.js_ Huge file, showing only transpiled relevant Crystal code: function ___crystal_main($argc,$argv) {
$argc = $argc|0;
$argv = $argv|0;
var label = 0, sp = 0;
sp = STACKTOP;
HEAP32[31] = $argc;
HEAP32[32] = $argv;
return 1;
}
function _main($argc,$argv) {
$argc = $argc|0;
$argv = $argv|0;
var label = 0, sp = 0;
sp = STACKTOP;
(___crystal_main($argc,$argv)|0);
return 0;
} |
From what I can tell Emscripten comes with a version of musl for its libc, so Crystal should now be able to support it thanks to @ysbaddaden's posix project. With an ABI it seems to me that the compiler might now have to be coded to switch between Emscripten LLVM and the regular System LLVM. Both have their own linker. |
I just realized that Emscripten comes with a tool to aid building projects with Makefiles. I got an interesting result after running Crystal through it. I'll look more into how the library dependencies should be handled soon. _emmake make_
|
I had the thought recently that it might be nice to target emscripten/asm.js with crystal :) (or the JVM? but that's a bit tricker). Interesting ideas... |
Now with Web Assembly in the picture, does it still make sense to target asm.js? Unless someone still strongly believes otherwise, I'd vote to close this issue. |
@mverzilli It's the same backend |
That was fast :). Thanks for the clarification! |
Of course! #3634 should still work with WebASM due to LLVM awesomeness, the only standing issue is the dependencies like Boehm |
The ruby world now has a stable near perfect ruby -> js transpiler. Of course stdlib stuff like threads, filemgt, etc etc and a very fee language features are simply not possible. However the subset makes it possible to code complete websites in a single language. A emscriptem targeted crystal subset would be a logical and highly desirable next step for a lot of people using opal and ruby. @keplersj any further news on your efforts? |
Compiling the language with an asm.js or wasm backend isn't entirely too difficult. I imagine that most of the code from my asm.js branch should still be applicable. The difficult part comes in with the Crystal standard library and garbage collection. If you create the subset you're talking about @catmando it should be more than possible to compile and execute it. |
@keplersj tx for quick reply. GC is written in C correct? So can it just also be run through emscriptem? |
I don't believe so. The Boehm GC relies on a lot of platform-specific, and IIRC some of it is also assembler. You'd basically have to redo the whole thing. |
@catmando If you create your own prelude with the subset you imagine, this technique I use above with emscripten should work to output runnable asm.js or wasm. That technique above certainly isn't foolproof, but it doesn't require a custom build of the compiler. Could be worth a try, might be helpful for building that web-focus subset you imagine. |
Maybe don't need GC because javascript land takes care of it for you? Not too familiar with asm.js... :) |
The GC has very little to do here. The problem is fibers and context switching via inline assembler. |
Neither wasm or asm.js well-support coroutines or multiple stacks, which makes porting fibers impractical. wasm has support for this timetabled, I think we'll be waiting for that and GC. And probably not asm.js - at least not with fibers. |
I guess rust can target wasm, what does it do with threads, just run single threaded, anybody know? Also wonder how golang does GC in wasm if it targets it... |
I started speccing a VM for WASM written in Crystal, but compiling Crystal into WASM seems like a much more practical project. I'll be keeping an eye out on this topic, and would like to contribute later on. Are there any actionable plans brewing at the moment? |
@mmKALLL no, we're waiting for wasm to mature. |
Can we close this in favor of #829 since "asm.js is old and wasm is its enw replacement" maybe? :) |
I'm gonna say no. In an ideal world the Crystal compiler would be able to output both asm.js and wasm, letting the user decide which output they need. If a user still needs to support browsers pre-wasm, or even just older JavaScript runtimes that support ES5 (with or without asm.js optimizations), they should still be able to output their codebases. |
FYI: I just put a discussion topic around this general topic: https://forum.crystal-lang.org/t/crystal-js-transpiler/903 |
Closing. asm.js is nowhere on the roadmap and probably obsolete with WASM support (which has already partly landed). |
_crystal build hello.cr --single-module --target "asmjs-unknown-emscripten"_
_crystal --version_
_cat hello.cr_
I was attempting an experiment to build a simple Crystal script, compile it, and transpile the Object file into JavaScript using Emscripten. However when I was using
emcc
to transpile the .o created in the .crystal folder I had gotten this error::After seeing this error I attempted to use the .bc file created in the same directory as well, and got this error:
I'll keep poking around to see if there is a fix I can do on my side, outside of the compiler, but I thought I'd pass this on to you guys to see what you might be able to do about it. There is of course the issue that asm.js is not an upstreamed backend in the LLVM yet, so I would wholly understand if you guys cannot do anything until then.
The text was updated successfully, but these errors were encountered: