11 ms·
Porffor: A from-scratch experimental ahead-of-time JS engine
- rubenfiszel 2y agoAt windmill.dev, when users deploy their code, we use Bun build (which is similar to esbuild) to bundle their scripts and all their dependencies into a single js file to load which improve cold start and memory usage. We store the bundle on s3 because of the size of the bundles. If we could bundle everything to native that would completely change the game since as good as bun's cold start is, you can't beat running straight native with a small binary.
- canadahonk 2y agoHey, dev here, I agree that is an interesting application which Porffor could potentially help with! Happy to chat sometime :)
- solumos 2y agoJust out of curiosity, how does the performance (compilation + runtime) compare to something like bun[0]? [0] https://bun.sh/ https://bun.sh/
- ijustlovemath 2y agoI'd love to know if there's a way to compile NodeJS to native libraries with this! I have a process [0], but it's a bit hacky and error prone [0] - https://github.com/ijustlovemath/jescx https://github.com/ijustlovemath/jescx
- awesomekling 2y agoOliver (the main developer) just announced that they’re going to work full time on Porffor: https://x.com/canadahonk/status/1818347311417938237 https://x.com/canadahonk/status/1818347311417938237
- simlevesque 2y agoFinanced by defunkt[1], GitHub cofounder and ex CEO, for an undisclosed future project. [1] https://news.ycombinator.com/user?id=defunkt https://news.ycombinator.com/user?id=defunkt
- pityJuke 2y agoAlso funded the Ladybird browser recently. Seems to like his web.
- pandemic_region 2y agoNot familiar with this stuff at all, is Porffor a js engine that Ladybird could end up using? Or are they still writing their own?
- Sammi 2y agoOr just two separate moonshots for now.
- meiraleal 2y agoIf that happens I would thank defunkt so much. Great way to spend money.
- simlevesque 2y agoYou'd have to wait before using any website using js. The AOT introduces a delay. Not sure it's achievable.
- giancarlostoro 2y agoPorffor compiles the JS to WASM, so it would be kind of a waste. Though there might be no reason the two projects cannot share some logic, like parsing the JS and such. I kind of doubt this is why its being funded. It sounds like a useful project.
- fyrn_ 2y ago
- obviouslynotme 2y agoI have thought about doing this and I just can't get around the fact that you can't get much better performance in JS. The best you could probably do is transpile the JS into V8 C++ calls. The really cool optimizations come from compiling TypeScript, or something close to it. You could use types to get enormous gains. Anything without typing gets the default slow JS calls. Interfaces can get reduced to vtables or maybe even straight calls, possibly on structs instead of maps. You could have an Int and Float type that degrade into Number that just sit inside registers. The main problem is that both TS and V8 are fast-moving, non-standard targets. You could only really do such a project with a big team. Maintaining compatibility would be a job by itself.
- ch_sm 2y agoSomewhat related to this idea is AssemblyScript https://www.assemblyscript.org https://www.assemblyscript.org
- lerpgame 2y agoYea I came here to say this, actually I was able to transpile a few typescript files from my project into assembly using GPT just for fun and it actually worked pretty well. If someone simply implements a strict typescript-like linter that is a subset of javascript and typescript that transpiles into assemblyscript, I think that would work better for AOT because then you can have more critical portions of the application in AOT and other parts that are non-critical in JIT and you get best of both worlds or something like that. making js backwards compatible and AOT sounds way too complicated.
- com2kid 2y agoEcmascript 4 was an attempt to add better types to the language, which sadly failed a long time ago. It'd be nice of TS at least allowed for specifying types like integer, allowing some of the newer TS aware runtimes could take advantage of the additional info, even if the main TS->JS compilation just treated `const val: int` the same as `const val: number`. I wonder if a syntax like const counter: Number<int> would be acceptable.
- syrusakbary 2y agoIt's awesome to see how more JS runtimes try to approach Wasm. This project reminds me to Static Hermes (the JS engine from Facebook to improve the speed of React Native projects on iOS and Android). I've spent a bit of time trying to review each, so hopefully this analysis will be useful for some readers. What are the main commonalities and differences between Static Hermes and Porffor? * They both aim for JS test262 conformance [1] * Porffor supports both Native and Wasm outputs while Static Hermes is mainly focused on Native outputs for now * Porffor is self-hosted (Porffor is written in pure JS and can compile itself), while Static Hermes relies on LLVM * Porffor currently doesn't support async/promise/await while Static Hermes does (with some limitations) * Static Hermes is written in C++ while Porffor is mainly JS * They both support TypeScript (although Static Hermes does it through transpiling the TS AST to Flow, while Porffor supports it natively) * Static Hermes has a fallback interpreter (to support `eval` and other hard-to-compile JS scenarios), while Porffor only supports AOT compiling (although, as I commented in other thread here, it maybe be possible to support `eval` in Porffor as well) In general, I'm excited to see if this project can gain some traction so we can speed-up Javascript engines one the Edge! Context: I'm Syrus, from Wasmer [3] [1] https://github.com/facebook/hermes/discussions/1137 https://github.com/facebook/hermes/discussions/1137 [2] https://github.com/tc39/test262 https://github.com/tc39/test262 [3] https://wasmer.io https://wasmer.io
- jonathanyc 2y agoJust wanted to say I really appreciated the high-quality comparison. How something compares to existing work is my #1 question whenever I read an announcement like this.
- deleted 2y ago[deleted]
- syrusakbary 2y agoThanks!
- wdb 2y agoYou make it sound bad to rely on LLVM.
- saagarjha 2y agoWhat happens when someone calls eval?
- syrusakbary 2y agoSince Porffor can compile itself (you can run the compiler inside of Porffor), any calls to eval could be compiled to Wasm (via executing the Porffor compiler in Porffor JS engine) and executed performantly on the same JS context * *or at least, in theory
- tasty_freeze 2y agoI haven't used it, but reading their landing page, Porffor says their runtime is vastly smaller because it is AOT. If the compiler had to be bundled with the executable, then the size of the executable would grow much larger.
- spartanatreyu 2y agoYeah, but you'd only need to include Porffor into compiled code if it used eval. And most devs stay away from eval for well-deserved security reasons.
- concerndc1tizen 2y agoThat wouldn't work: The Wasm spec does not allow for modifying an already running program (e.g. JIT). AFAIK the only option is to include an interpreter.
- syrusakbary 2y agoYou don't need to modify an already running program, you can plug new functions into an existing Wasm program via a table, and even attach variables via globals or function arguments. I'd recommend checking the work on making SpiderMonkey emit Wasm as a backend
- david2ndaccount 2y ago
- THBC 2y agoThis seems like an opaque supply chain attack waiting to happen.
- nick_g 2y agoI'm a bit suspicious of the versioning scheme described here[0] If some change were required which introduced a regression on some Test262 tests, it could cause the version number to regress as well. This means Porffor cannot have both a version number which increases monotonically and the ability to introduce necessary changes which cause Test262 regressions [0] https://github.com/CanadaHonk/porffor?tab=readme-ov-file#versioning https://github.com/CanadaHonk/porffor?tab=readme-ov-file#ver...
- derdi 2y agoPresumably the idea is that any work that causes Test262 regressions is temporary, takes place in a separate branch, and is only merged to main once the branch also contains all the necessary fixes to make the regressions go away again. A new version number would only be used once that merge happens.
- canadahonk 2y agoExactly. The versioning system is definitely unique and controversial, but I think it fits for a fast moving project like this, so I don't have to really consider versioning which could slow development. When it becomes more stable, I'll likely move to a more traditional semver scheme from 1.0.
- apgwoz 2y agoWhat happens if there’s a regression in coverage, maybe due to a large sweeping change, and you go from 0.40 -> 0.35 ?
- astrobe_ 2y agoThere's the commit hash. Basically the "version number" is the commit hash, the human-generated (version) numbers added to it are merely progress indicators, which might be randomly useful. But for a project that has 1 branch, 0 tags and nearly 2000 commits, that's not really important.
- rvnx 2y agoSeems like the same idea that Facebook had with PHP which was to transpile PHP to C. It was called hiphop-php, then they eventually gave up, before creating hhvm on a complete new concept.
- pjmlp 2y agoHistorically the sequence is a bit different. After HHVM proved that its JIT compilation engine was faster than their HipHop AOT attempt, did they decided to focus only on HHVM going forward.
- your-username 2y ago[flagged]
- Borkdude 2y agoI got "TodoError: no generation for ImportDeclaration!" for this script: import * as squint_core from 'squint-cljs/core.js'; console.log("hello");
- mproud 2y ago“Purple” in Welsh
- zem 2y agowith etymology from the greek for purple; the english "porphyry" (a purple mineral) is probably the commonest word with the same root.
- CharlesW 2y agoWhat subtleties am I missing that makes "ahead-of-time JS engine" a better description than "JS-to-Wasm compiler"? (If it's mostly a framing strategy, that's cool too.)
- chillfox 2y agoThere are already projects that does JS-to-WASM by bundling a JS interpreter. So, it's likely to make the difference to those clearer.
- canadahonk 2y agoYep! Also as it is technically more of an engine/runtime (sometimes) than "just" a compiler, folks in the JS space are more familiar with engine as a term :)
- FpUser 2y agoI find this very interesting. Keep it up and bring it to production shape
- WatchDog 2y agoHow does this compare to quickJS, which can also compile JS to native code(with a C compiler)
- spacechild1 2y agoI think QuickJS only compiles to bytecode and then embeds it together with the interpreter in an executable. The JS itself is still interpreted. Others please correct me if I'm wrong.
- xiaodai 2y agoStop trying to retrofit garbage on garbage. Go direct to WebAsm already
- Sytten 2y agoIts refreshing to see all the various JS engines that are out there for various usecases. I have been working on providing quickjs with more node compatible API through llrt [1] for embedding into applications for plugins. [1] https://github.com/awslabs/llrt https://github.com/awslabs/llrt
- userbinator 2y agoPorffor can compile to real native binaries without just packaging a runtime like existing solutions. Any language that allows generating and interpreting its own code at runtime will have the "eval problem". From some other comments here, it sounds like Porffor's solution is to simply ignore it.
- draw_down 2y ago[dead]
- brundolf 2y agoThere's a subset of JS that's trivially compilable, it's the long tail of other stuff that's hard. But cool to see research happening on where that boundary lies and how much benefit can be had for that subset
- vanderZwan 2y agoI unironically appreciate that it supports String.blink. It's always a good sign if the developer has a sense of humor and playfulness.
- chrismorgan 2y agoIf it’s interested in behaving as though “the ECMAScript host is a web browser”, of course it does, it’s part of the spec: https://tc39.es/ecma262/multipage/additional-ecmascript-features-for-web-browsers.html#sec-string.prototype.blink https://tc39.es/ecma262/multipage/additional-ecmascript-feat.... And given how trivial it is (function() { return "<blink>" + this + "</blink>"; }), it makes a fair amount of sense to implement it even if the ECMAScript host is not a web browser, in which case it’s optional (see the top of the linked document). I wouldn’t expect it to have any association with “a sense of humor or playfulness” whatsoever.
- vanderZwan 2y agoThe reason I would argue that it does imply a sense of humor is that on any web browser that supports WASM, the <blink> tag itself has been deprecated and non-functional for ages. In fact, it doesn't even have an entry on MDN, only an indirect reference through String.blink() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/blink https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- chrismorgan 2y ago<blink>, sure, but String.prototype.blink is still part of the spec, and unlike the HTML Standard, the ECMAScript specs are much more pseudocode that you largely just copy and turn into actual code as necessary, to the point that, if as an ECMAScript host it’s playing the web browser, I’d be extremely surprised (as in, “wait, what!? This is literally the weirdest technical thing I’ve seen all year, maybe this decade”) if that one method wasn’t there. When you’re implementing specs written like this, you just do it all; you don’t—you never—pick and choose based on “that thing is obsolete and no one uses it anyway”.
- giancarlostoro 2y agoThe most interesting bit about Porffor in my eyes is it lets JavaScript compete with something like Blazor (or allows JS to stand its ground), which kind of makes using any JS in your project redundant, since all your front-end logic can be done in C#. The reason I say this is, because obviously, there are JS devs, but if WASM tooling in other languages grows it will make JS redundant or feel incomplete / outcompeted. I wont be surprised to see a SPA framework that uses Porffor once it is more mature, or even the major ones using it as part of their tooling. WASM is the next step after SPA's essentially. If you have never touched Blazor, I recommend you check it out via youtube video if you don't do any C#, it is impressive. Kudos to Microsoft for it. I have had 0 need or use for JavaScript since using it.
- tempodox 2y agoThat sounds like we could finally get rid of the worst programming language to ever reach as widespread adoption as JS has today. I can't wait!
- deleted 2y ago[deleted]
- xyproto 2y agoPromising, but a few rough edges. > 1+1 2 > help Uncaught ReferenceError: help is not defined at exports.<computed> [as main] (file:///opt/homebrew/lib/node_modules/porffor/compiler/wrap.js:494:19) at REPLServer.run (file:///opt/homebrew/lib/node_modules/porffor/runner/repl.js:98:27) at bound (node:domain:432:15) at REPLServer.runBound [as eval] (node:domain:443:12) at REPLServer.onLine (node:repl:927:10) at REPLServer.emit (node:events:532:35) at REPLServer.emit (node:domain:488:12) at [_onLine] [as _onLine] (node:internal/readline/interface:416:12) at [_line] [as _line] (node:internal/readline/interface:887:18)