-
Notifications
You must be signed in to change notification settings - Fork 396
Initial implementation of the WebAssembly backend. #4988
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
Conversation
de9bb98
to
b5ed18d
Compare
The build is now green. The code should be good to go. I have started some Readme documentation of the compilation scheme, to complement the code comments which are more local. I'll continue in the coming days. @gzm0 I expect reviewing this will take time (like, weeks or more). Beside the compilation scheme, are there things you would like to see and that would help you review? I'm already marking you as reviewer, but it's fine if you wait for me to provide everything you will need before starting, obviously. Also general note about future edits: from now on I will refrain from force-pushing on this branch. I will only add commits, even if they are wip addressing comments (but hopefully each passing the CI regardless). We'll rebase when all the reviewing process over. |
I think for now, this is OK. My plan was to first focus on the "outer structure" anyways, so for this, I do not need to know a lot (anything?) about the compilation scheme. One thing that I'd like to get out of this PR is to get a better understanding how reviews will work going forward in this repository between @sjrd, @tanishiking and me. Basically, I'd like to understand if we need more "formal" structure to ensure that:
In any case though, I think we'll be better equipped at the end of the review of this PR to answer this question. I just wanted to put it out there, so we do not forget.
FWIW: For me Github's "viewed" state is likely going to be much more important than individual commits. So for example, feel free to amend the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First review pass on everything but wasmemitter
and webassembly
.
linker-interface/shared/src/main/scala/org/scalajs/linker/interface/StandardConfig.scala
Outdated
Show resolved
Hide resolved
test-suite/js/src/test/scala/org/scalajs/testsuite/compiler/RuntimeTypeTestsJSTest.scala
Show resolved
Hide resolved
test-suite-ex/shared/src/test/scala/org/scalajs/testsuite/javalib/lang/ClassTestEx.scala
Outdated
Show resolved
Hide resolved
test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkingInfoTest.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/DerivedIRFiles.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/WebAssemblyLinkerBackend.scala
Show resolved
Hide resolved
One thing @sjrd you might be able to provide that helps me, is a "suggested order of review" for the two new packages. (I was assuming |
Good point. I would suggest the following: In
This should be enough of In
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't looked at the code for the compilation scheme much, only checking the differences from the book's repository. (Since I've reviewed the most of code there through the interaction in scala-wasm repo).
I left a few comments but it looks good to me, and wasmemitter/README.md
looks great so far.
test-suite/js/src/test/scala/org/scalajs/testsuite/library/LinkingInfoTest.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/WebAssemblyLinkerBackend.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
test-bridge/src/main/scala/org/scalajs/testing/bridge/HTMLRunner.scala
Outdated
Show resolved
Hide resolved
FYI, I'll mark comments I made as resolved once I feel the discussion is resolved. @tanishiking @sjrd do you feel we need to agree on a scheme on how to resolve comments? (e.g. opener only resolves?) |
I think opener resolves, unless it's a typo or something like that. |
c43750a
to
6e38cb4
Compare
I believe I have addressed everything so far.
|
6f64fc2
to
5b1cfbd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know the README is WIP, but LGTM from my side 💯
23e3538
to
86b8f6c
Compare
I think I'm done with the README at this point. There are many more things I could write about, but they are more local, so comments in the code should cover them well. I focused on things that have a global impact across the backend. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed comments in ClassEmitter
and added details about the overall ordering of definitions in the Readme.
Sorry for the delay in addressing the latest batch. I'm mostly on vacation these days.
linker/shared/src/main/scala/org/scalajs/linker/backend/WebAssemblyLinkerBackend.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed comments in CoreWasmLib
, DerivedClasses
, and some comments in Emitter
but definitely not all of them yet.
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of most recent changes and answers to some comments.
I have also done a full "resolution" pass.
Sorry for the delay in addressing the latest batch. I'm mostly on vacation these days.
There is no need to apologize. It's not like I don't have anything to do anymore :P
Enjoy your vacation (if you are still off :)).
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/WebAssemblyLinkerBackend.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/WebAssemblyLinkerBackend.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/ClassEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressing some more comments.
Main todos:
- Moving from
Emitter
toClassEmitter
stuff in thestart
function (not yet convinced that would be better) - Extracting
StringPool
- Comments in
TextWriter
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/LoaderContent.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/LoaderContent.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/LoaderContent.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/SWasmGen.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/FunctionBuilder.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/FunctionBuilder.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Phew, I think I have addressed everything so far.
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oops, I had forgotten a bunch of comments in TextWriter
.
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/CoreWasmLib.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/TextWriter.scala
Outdated
Show resolved
Hide resolved
If an object is sealed, `captureStackTrace` throws an exception. This will happen for WebAssembly objects. We now detect this case and fall back to instantiating a dedicated `js.Error` object.
We now directly use `import("./main.js")` or `require("./main.js")` rather than relying on the compilation scheme of `js.dynamicImport`. This will allow `ExportLoopback` to work under WebAssembly, although the initial implementation will not support multiple modules.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of everything except BinaryWriter and the points I have explicitly left comments (IIRC, primarily the dragons).
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/VarGen.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/VarGen.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/VarGen.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/VarGen.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/WasmContext.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed some comments. I need to look more deeply into the possible bug in computeItableBuckets
.
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/LoaderContent.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
Well ... it turns out we didn't need Phase 2 of the bucket assignment algorithm at all! I added a few commits that should address the latest comments on that algorithm. @tanishiking Could you double-check what I did there? Here is a gist with the bucket assignments computed for the helloworld and for the test suite: (also the recent changes did not alter the number of buckets allocated for the test suite -- I did not check the helloworld) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I left one question, and otherwise the change looks reasonable 👍
It's interesting to note that there are barely more buckets for the full test suite than for the helloworld. We basically get 40 buckets because of the huge mess that is the collections hierarchy, but not much more beyond that.
Yeah, that happens when a class has a bunch of superclasses/interfaces, as all those superclasses share the same subclass and therefore can't be assigned to the same bucket. This situation applies to the hierarchy in the Scala collection libraries :/
I believe most applications have that number of buckets, but not many go beyond that, as long as the applications define a more deeply nested data hierarchy than the Scala collections.

linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Review of BinaryWriter (mostly minor things) & follow-up changes (IIRC no additional comments).
At this point, all remaining things to be done are in unresolved conversations (some of them are TODOs for myself).
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/LoaderContent.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/WasmContext.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/WasmContext.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/BinaryWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/BinaryWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/BinaryWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/BinaryWriter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed comments in BinaryWriter
, but not elsewhere yet.
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/BinaryWriter.scala
Outdated
Show resolved
Hide resolved
And I addressed the remaining comments that were not resolved yet, AFAICT. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Complete review. The dragons seem to be implemented nicely. So it is not that terrible to understand :)
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/WasmContext.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Preprocessor.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/Emitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/FunctionBuilder.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed latest batch of comments.
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/WasmContext.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Outdated
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/wasmemitter/FunctionEmitter.scala
Show resolved
Hide resolved
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/FunctionBuilder.scala
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after squashing (down to 4 total commits).
linker/shared/src/main/scala/org/scalajs/linker/backend/webassembly/FunctionBuilder.scala
Show resolved
Hide resolved
This commit contains the initial implementation of the WebAssembly backend. This backend is still experimental, in the sense that: * We may remove it in a future Minor version, if we decide that it has a better place elsewhere, and * Newer minor versions may produce WebAssembly code that requires more recent WebAssembly features. The WebAssembly backend silently ignores `@JSExport` and `@JSExportAll` annotations. It is otherwise supposed to support the full Scala.js language semantics. Currently, the backend only supports some configurations of the linker. It requires: * No optimizer, * Unchecked semantics for undefined behaviors, * Strict floats, and * ES modules. Some of those will be relaxed in the future, definitely including the first two. Co-authored-by: Rikito Taniguchi <rikiriki1238@gmail.com>
Thank you so much @gzm0 for this epic review! |
This commit contains the initial implementation of the WebAssembly backend. This backend is still experimental, in the sense that:
The WebAssembly backend silently ignores
@JSExport
and@JSExportAll
annotations. It is otherwise supposed to support the full Scala.js language semantics.Currently, the backend only supports some configurations of the linker. It requires:
Some of those will be relaxed in the future, definitely including the first two.
Co-authored-by: @tanishiking
Past history of the development of this backend may be found at https://github.com/tanishiking/scala-wasm
We did not make any effort in preserving the git history when creating this PR, as it followed a very aggressive commit policy, which would not fit this repository anyway.