Live data from Hacker News

JSIR: A High-Level IR for JavaScript

discourse.llvm.org

21–30 of 33 posts

Re: JSIR: A High-Level IR for JavaScript

#22
post #18
post #15

It's funny they bother to bring up the half dead "Google Closure Compiler" as an example. And my dumb brain still don't understand how IR is "better" than AST after reading this post. Current AST based JS tools working reasonably well, and it's not clear to me how introducing this JSIR helps tool authors or downstream users, when there are all those roadblocks mentioned at the end.

Why is it half dead? They only jettisoned the ancient support library, the compiler itself AFAIK remains best in class and has commits on GitHub as of 15 hours ago

Something as important as https://github.com/google/closure-compiler/issues/2731 that is in ES2022 standard (Yes, released near 4 years ago) is still not implemented. Lots of new code don't compile with it.

It has become a liability in the build process and people are getting rid of it.

Re: JSIR: A High-Level IR for JavaScript

#23
post #20

Earlier quoted context omitted.

I think the WASM world is a clear example that bridges the gap you're describing. You usually compile from SSA to WASM bytecode, and then immediately JIT (Cranelift) by reconstructing an SSA-like graph IR. If you look at the flow, it's basically: Graph IR -> WASM (stack-based bytecode) -> Graph IR So the stack-based IR is used as a kind of IR serialization layer. Then I realized that this works well because a stack-b…

Only compilers that already had an SSA-based pipeline transform SSA to stack-based for Wasm. And several don't like that they have to comply with Wasm structured control flow (which, granted, is independent from SSA). Compilers that have been using an expression-based IR directly compile to Wasm without using an SSA intermediary.

I was imprecise, I was specifically thinking of already SSA-based tech.

My broader point is that for SSA-based pipelines targeting Wasm, translation between SSA/graph IR and stack-based IR is largely mechanical and efficient. Whether a compiler uses SSA as an intermediary or goes straight from an AST to Wasm, the fact remains that you can round-trip between a SSA-like IR and a stack-based IR without losing the underlying dataflow information.

Yeah, mapping is not canonical and some non-semantic structure is not preserved (evaluation order, materialization points, join encoding, CFG reshaping for structured control and probably some more structure I'm not familiar with), but optimization power is unaffected.

And JSIR seems to be based on an even stronger assumption.

Would appreciate corrections if you see things differently.

Re: JSIR: A High-Level IR for JavaScript

#24

asking as someone who is writing a game engine in javascript with the intention to 'transpile' the games' source into a C# project for a native runtime: this provides a map that allows automated translation from javascript source to C# source, right?

No. JSIR is primarily for JS -> IR -> JS for analysis and source-to-source transformation. It's not a ready-made bridge for emitting other languages

You could use it as an intermediate form in a JS->C# pipeline, but you still have to define a subset of JavaScript that lowers cleanly to your target C# runtime and implementing the IR->C# lowering yourself.

I'd imagine the hard part is not the IR, but aligning the JavaScript semantics (object model, closures, prototypes etc.) with C# (static type system, different execution model..).

Re: JSIR: A High-Level IR for JavaScript

#25

They're presenting this under the banner "the need for source to source transformations." That seems a bit disingenuous given this is not a source-preserving IR! All comments and nonstandard spacing would be completely removed from your code if you gave it a round trip through this format. That doesn't sound like 99.9% source recovery to me...

The 99.9% is less impressive than you'd think, currently they're not even keeping the same program behaviour 0.1% of the time. They also mention AST in the pipeline, not CST, so I wouldn't expect source-preservation to be a direct goal.

Also, if you use a nonstandard spacing, I'd say that's on you to preserve a mechanical Source-AST mapping if you want to use any tool that mentions dataflow analysis & transforms.

As a side note, comments are much trickier than non-standard spacing if their positioning is semantic.

Re: JSIR: A High-Level IR for JavaScript

#26

asking as someone who is writing a game engine in javascript with the intention to 'transpile' the games' source into a C# project for a native runtime: this provides a map that allows automated translation from javascript source to C# source, right?

It's probably easier to add a JS Guest Language to the CLR than transpile to C#

CLR already has multiple Language front-ends (C#, F#, VB, IronPython)

Re: JSIR: A High-Level IR for JavaScript

#27

asking as someone who is writing a game engine in javascript with the intention to 'transpile' the games' source into a C# project for a native runtime: this provides a map that allows automated translation from javascript source to C# source, right?

No. JSIR is primarily for JS -> IR -> JS for analysis and source-to-source transformation. It's not a ready-made bridge for emitting other languages You could use it as an intermediate form in a JS->C# pipeline, but you still have to define a subset of JavaScript that lowers cleanly to your target C# runtime and implementing the IR->C# lowering yourself. I'd imagine the hard part is not the IR, but aligning the JavaS…

Right on. That makes sense. Thanks for spelling it out!

I do think aligning the semantics will be the easier part, honestly, because I'm only trying to transpile the supported source for the game engine. Since that's all written in typescript and I'm not guaranteeing full parity if you are trying to transpile arbitrary ts/js (only the source that can be parsed the same way the game engine is parsed), I'm expecting it to be a near 1-to-1 conversion. I started writing everything in C# and copied the structure to JS, knowing that this was the eventual plan, so the JS can actually be re-written as C# with a pretty simple regex tokenizer.

My hope, here, is that by having the code morphed into an IR, that the IR would be some kind of well-known IR that - for instance - C# could also be morphed into and - therefore - would allow automatic parsing back and forth. From what you're saying, though, it sounds like IRs don't use a common structure for describing code (I'm guessing because of the semantic misalignment you mention between a wide variety of different paradigms?), so this would only work if I made the map from IR to C# which would be just as complex (or more so) than just regexing my JS into C#. If I've got that right, that's a bummer, but understandable. If I'm wrong, though, happy to learn more!

Re: JSIR: A High-Level IR for JavaScript

#28
post #20

Earlier quoted context omitted.

Only compilers that already had an SSA-based pipeline transform SSA to stack-based for Wasm. And several don't like that they have to comply with Wasm structured control flow (which, granted, is independent from SSA). Compilers that have been using an expression-based IR directly compile to Wasm without using an SSA intermediary.

I was imprecise, I was specifically thinking of already SSA-based tech. My broader point is that for SSA-based pipelines targeting Wasm, translation between SSA/graph IR and stack-based IR is largely mechanical and efficient. Whether a compiler uses SSA as an intermediary or goes straight from an AST to Wasm, the fact remains that you can round-trip between a SSA-like IR and a stack-based IR without losing the underl…

Right. I believe we are in agreement on that.

Re: JSIR: A High-Level IR for JavaScript

#29

asking as someone who is writing a game engine in javascript with the intention to 'transpile' the games' source into a C# project for a native runtime: this provides a map that allows automated translation from javascript source to C# source, right?

It's probably easier to add a JS Guest Language to the CLR than transpile to C# CLR already has multiple Language front-ends (C#, F#, VB, IronPython)

A solid suggestion, but a big point of porting it to C# is the performance gains, which the CLR would mitigate. I know it'll be faster than running in a browser - where the game will also run - but if you're offering something for "performance", I don't think the time is best spent on making my job of composing the package easier. I think I'd rather try to figure out how to go whole-hog and compile as much of the game into an AOT package as possible. But, for what it's worth, the entire game engine was written in C# and ported into JS for the express purpose of being able to back-port the packaged code into C#. So I'm hoping it's not too onerous to do the native transpilation, either.

Re: JSIR: A High-Level IR for JavaScript

#30

Earlier quoted context omitted.

No. JSIR is primarily for JS -> IR -> JS for analysis and source-to-source transformation. It's not a ready-made bridge for emitting other languages You could use it as an intermediate form in a JS->C# pipeline, but you still have to define a subset of JavaScript that lowers cleanly to your target C# runtime and implementing the IR->C# lowering yourself. I'd imagine the hard part is not the IR, but aligning the JavaS…

Right on. That makes sense. Thanks for spelling it out! I do think aligning the semantics will be the easier part, honestly, because I'm only trying to transpile the supported source for the game engine. Since that's all written in typescript and I'm not guaranteeing full parity if you are trying to transpile arbitrary ts/js (only the source that can be parsed the same way the game engine is parsed), I'm expecting it…

I don't see anything wrong that would disqualify your plan. But if the alternative is regex, and you're writing already in TypeScript, you may take a look at ts-morph [0]. TS has very good compiler APIs and that gets you something much safer than text-based replacement while still staying relatively small for a constrained subset. ts-morph wraps those APIs cleanly.

Btw, JS doesn't even have an official bytecode. The spec is defined at the language semantics level, so each engine/toolchain invents its own internal representation.

[0] https://github.com/dsherret/ts-morph

Post reply on HN