emscripten-core / emscripten

Emscripten: An LLVM-to-WebAssembly Compiler
Other
25.79k stars 3.31k forks source link

Compile to ASM.js #18013

Closed LukasOgunfeitimi closed 5 months ago

LukasOgunfeitimi commented 2 years ago

Is it still possible to compile to ASM.js and if so what options do i need to use?

I have tried to use WASM=0 but asm.js isnt outputted.

kripken commented 2 years ago

WASM=0 emits JS, correct. It isn't valid asm.js.

You'd need to use an older version of emcc for that.

Why do you need asm.js, btw?

LukasOgunfeitimi commented 2 years ago

Could you point in the right direction of the version I would need?

And I would just like to make a comparison between asm.js, cheerp and wasm to see which would be most appropriate for a project.

sbc100 commented 2 years ago

asm.js isn't really a thing anymore now the wasm exists. I'm not even sure if modern browser still contains special optimizations for it. The closest thing would be building -sWASM=0 which is generated JS code, but its almost certainly worse that just use wasm (which is the default).

Also, as far as I know cheerp also generates wasm, so perhaps you mean you want to compare emscripten-generated wasm with cheerp-generated wasm?

kripken commented 2 years ago

@lukasXOR

According to the changelog the last verison with fastcomp support, which is what compiled asm.js, was 1.40.1. So you can use that, but make sure to specify to use fastcomp and not upstream, as upstream was the default. Or, 1.38.48 was the last version with fastcomp on by default.

(But, to add to what @sbc100 just said, I'd be very surprised to hear about a use case where asm.js is best these days. Maybe the only thing I can think of is a frozen browser version from back in the asm.js days..?)

LukasOgunfeitimi commented 1 year ago

@kripken hi so im using 1.38.48, do you know what options i should use -s WASM=0 is still giving me wasm on this version. What can i use to output just asm.js? thanks

kripken commented 1 year ago

@lukasXOR That is the right flag, so I'm not sure what's going wrong. Maybe you are seeing old output files from a previous compilation, or maybe the flag isn't being passed right on the commandline somehow (could be a build system issue with quoting, or such).

LukasOgunfeitimi commented 1 year ago

@kripken do you remember what version you used for your BananaBread game

kripken commented 1 year ago

@lukasXOR Sorry, I don't. But I was using the latest version at the time. So perhaps you can see in the git changes there what date that was, and find the last emscripten release before that date from the emscripten changelog.

PoneyClairDeLune commented 1 year ago

asm.js isn't really a thing anymore now the wasm exists. I'm not even sure if modern browser still contains special optimizations for it. The closest thing would be building -sWASM=0 which is generated JS code, but its almost certainly worse that just use wasm (which is the default).

Also, as far as I know cheerp also generates wasm, so perhaps you mean you want to compare emscripten-generated wasm with cheerp-generated wasm?

SpiderMonkey still has special optimizations built-in for asm.js, enabled via "use asm";. V8 never did.

sbc100 commented 1 year ago

V8 never did.

IIUC that is not true. v8 had a mode where it would use a special optimized path for "use asm" files that used the same path wasm files used. I believe this has since been removed though.

I think we can probably close this issue now since emscripten no longer supports outputting asm.js syntax ?

PoneyClairDeLune commented 1 year ago

I think we can probably close this issue now since emscripten no longer supports outputting asm.js syntax ?

Why? Isn't the issue for re-enabling ASM.js support? And what does vanilla JS have over ASM.js for Emscripten to favour vanilla over ASM.js?

sbc100 commented 1 year ago

We have no plans for bring back asm.js support at this time. Emscripten's support for JS is via that wasm2js tool in binaryen. IIRC, when we developed this tool we made it a non-goal to support the strict asm.js syntax since it would have made building and testing that tool more complex without any advantages. The rational here is that the JS output of emscripten was specifically for targetting older/legacy devices (such as TVs) where the JS engine could not be upgraded. All modern engines should have wasm support and no modern engines are investing asm.js support (indeed v8 completely removed their asm-specific support).

PoneyClairDeLune commented 1 year ago

ASM.js is a valid strict subset of JS features. It should run fine on legacy devices, though I see your point of it being hard to debug. Gonna be hard to find a solution with ASM.js compile targets...

sbc100 commented 1 year ago

Its not that asm.js won't run everywhere, is that just that wasm2js doesn't generate it. If there were a very compelling reason it might be possible to update wasm2js to output strict asm.js.

@PoneyClairDeLune is there some reason that you need strict asm.js output?

The output of wasm2js is very much like like asm.js but doesn't strictly conform. I wouldn't that one or other other is any easier to debug.

PoneyClairDeLune commented 1 year ago

Like I said, some legacy runtimes offer optimizations for ASM.js. Especially for Firefox ESR 52 and earlier, maybe Chrome 49 and earlier too. Those specific browser versions are the ones able to run on Windows XP.

sbc100 commented 1 year ago

Like I said, some legacy runtimes offer optimizations for ASM.js. Especially for Firefox ESR 52 and earlier, maybe Chrome 49 and earlier too. Those specific browser versions are the ones able to run on Windows XP.

Do you have a lot of users on those platforms? Are they able to run emscripten (with -sWASM=0) output currently?

PoneyClairDeLune commented 1 year ago

Users? No, I don't maintain a C/C++ project, but rather seek to build a project (TiMidity++) for running in browsers on Windows XP. Raw JS works, but the performance isn't too great. The most modern OS usable in the Desktop Music MIDI scene would be Windows XP, it has to be able to run there to aim for better workflow integration.

sbc100 commented 1 year ago

Sorry, by "users" I meant users of your project/website (TiMidity++). How many people are using use website on Windows XP? Is there some reason why your project in particular needs to run on Windows XP? Just curious.

PoneyClairDeLune commented 6 months ago

How many people are using use website on Windows XP?

100% when native MIDI interfaces on soundcards or proprietary standard-compliant soft synths are used. Those on Windows 9x, while enjoying a wider selection, are just too much hassle to support, and they can get XP programs running with KernelEx anyways.

Is there some reason why your project in particular needs to run on Windows XP?

As I said, most programs in the DTM (desktop music) scene are generally over 20 years old, some even starting to reach their 30s, and all they supported were either Windows 9x or Windows XP. They just refuse to work on anything newer than Windows XP SP3.

I'll go for version 1.40.1 or version 1.38.48 then.

cyan-2048 commented 6 months ago

someone please make a guide on how to setup emscripten to compile to asm.js (even if you'd have to use an outdated version), although there's little to no demand, asm.js is pretty much the only choice for KaiOS 2.5 devices.

sbc100 commented 6 months ago

someone please make a guide on how to setup emscripten to compile to asm.js (even if you'd have to use an outdated version), although there's little to no demand, asm.js is pretty much the only choice for KaiOS 2.5 devices.

You can target pure JS using -sWASM=0. Does that work for your case?

kripken commented 6 months ago

If you do need an ancient version for actual asm.js support, this should work:

# get emsdk from git, then enter that directory
..
# get an older emsdk
git checkout 1.39.20
# get an older emscripten
./emsdk install 1.39.20-fastcomp
./emsdk activate 1.39.20-fastcomp
# build without wasm
emcc -s WASM=0 [..]

Out of curiosity, is that OS version still common? KaiOS 2.5 seems to be a few years old, and 3.0 from 2021 (almost 3 years ago) had a major Gecko update that should include wasm support. But I am not sure how older KaiOS devices update their OS.

cyan-2048 commented 5 months ago

If you do need an ancient version for actual asm.js support, this should work:

# get emsdk from git, then enter that directory
..
# get an older emsdk
git checkout 1.39.20
# get an older emscripten
./emsdk install 1.39.20-fastcomp
./emsdk activate 1.39.20-fastcomp
# build without wasm
emcc -s WASM=0 [..]

Out of curiosity, is that OS version still common? KaiOS 2.5 seems to be a few years old, and 3.0 from 2021 (almost 3 years ago) had a major Gecko update that should include wasm support. But I am not sure how older KaiOS devices update their OS.

Kaiostech claims they have over 100 million users, and the majority of those users use KaiOS 2.5, because they didn't make it possible for KaiOS 2.5 users to upgrade to KaiOS 3.0. Furthermore, KaiOS 3.0 was first released in north america alone.

KaiOS 2.5 is based on Firefox 48, while KaiOS 3.0 is based on Firefox 84.

I think asm.js is definitely useful for use on KaiOS devices, I've heard a bunch of other devs earning big money from KaiOS app development.

IIRC, the first non-US KaiOS 3.0 device released in Japan just recently, it's kinda ironic that kaiostech advertises these devices as a "bridge" for technological divide, yet most of their users suffer from old gecko and most websites won't even work properly.

cyan-2048 commented 5 months ago

someone please make a guide on how to setup emscripten to compile to asm.js (even if you'd have to use an outdated version), although there's little to no demand, asm.js is pretty much the only choice for KaiOS 2.5 devices.

You can target pure JS using -sWASM=0. Does that work for your case?

For this one, I notice that pure js isn't doing well on a KaiOS device, apparently using actual asm.js on KaiOS it will pre-compile asm.js to native code so that might help. I'll try the git checkout method mentioned by someone else later.

sbc100 commented 5 months ago

For this one, I notice that pure js isn't doing well on a KaiOS device, apparently using actual asm.js on KaiOS it will pre-compile asm.js to native code so that might help. I'll try the git checkout method mentioned by someone else later.

Can you explain what you mean by "isn't doing well"? If/when you do get actual asm.js running can you confirm that the "isn't doing well" goes away, or if it continues. That seems like it would be good data point.

cyan-2048 commented 5 months ago

For this one, I notice that pure js isn't doing well on a KaiOS device, apparently using actual asm.js on KaiOS it will pre-compile asm.js to native code so that might help. I'll try the git checkout method mentioned by someone else later.

Can you explain what you mean by "isn't doing well"? If/when you do get actual asm.js running can you confirm that the "isn't doing well" goes away, or if it continues. That seems like it would be good data point.

"Isn't doing well" is because I'm trying to make discord voice calls work for Nokia KaiOS 2.5 devices, one requirement is opus encoding, so I use xiph opus thing, the problem occurs when the main thread freezes encoding raw pcm, discord disconnects because setInterval also stop working as expected. I'm going to try asm.js + WebWorkers and see if there will be an improvement. This isn't a problem at all for KaiOS 3.0 devices since it supports WebRTC properly anyways, so I don't even need to encode manually.

sbc100 commented 5 months ago

Thanks for the explanation.

If building for real asm.js as opposed to plain js makes that difference then hopefully the old 1.39.20 is up to the job. Please let us know how it goes.

cyan-2048 commented 5 months ago

Thanks for the explanation.

If building for real asm.js as opposed to plain js makes that difference then hopefully the old 1.39.20 is up to the job. Please let us know how it goes.

cool so here's what happened, it did actually make a difference, 8 seconds of raw pcm now gets encoded to opus in just 2-3 seconds (this is an improvement lmao, with pure js it takes 7 seconds of freezing), very dope this will be even better when I start using web workers.

and the old emscripten build worked just fine, thank you so much @kripken for the instructions

sbc100 commented 5 months ago

OK, closing this one out for now then.

cyan-2048 commented 5 months ago

yep asm.js works really well https://github.com/emscripten-core/emscripten/assets/72785466/f1e48172-5a60-4c77-99e6-10d1a0a79e69