Live data from Hacker News

Porffor: A from-scratch experimental ahead-of-time JS engine

porffor.dev

11–20 of 148 posts

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#13
I'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#ver...

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#14

I 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 may…

At least without additional extensions, TypeScript would help less than you think. It just wasn’t designed for the job.

As a simple example - TypeScript doesn’t distinguish between integers and floats; they’re all just numbers. So all array accesses need casting. A TypeScript designed to aid static compilation likely would have that distinction.

But the big elephant in the room is TypeScript’s structural subtyping. The nature of this makes it effectively impossible for the compiler to statically determine the physical structure of any non-primitive argument passed into a function. This gives you worse-than-JIT performance on all field access, since JITs can perform dynamic shape analysis.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#15
post #10

I 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 may…

Ecmascript 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 would be ac…

Number is not semantically compatible with raw 64-bit integer, so you might as well wish for a native

    const counter = UInt64(42);
The current state of the art is

    const counter = BigInt.asUintN(64, 42);

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#16
post #10

I 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 may…

Ecmascript 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 would be ac…

Yeah, that is why I said TS (or something similar). TS made some decisions that make sense at the time, but do not help compilation. The complexity of its typing system is another problem. I'm pretty sure that it is Turing-complete. That doesn't remove feasibility, but it increases the complexity of compiling it by a whole lot. When you add onto this the fact that "the compiler is the spec," you really get bogged down. It would be much easier to recognize a sensible subset of TS. You could probably even have the type checker throw a WTFisThisGuyDoing flag and just immediately downgrade it to an any.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#18

What happens when someone calls eval?

Since 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

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#19
post #14

I 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 may…

At least without additional extensions, TypeScript would help less than you think. It just wasn’t designed for the job. As a simple example - TypeScript doesn’t distinguish between integers and floats; they’re all just numbers. So all array accesses need casting. A TypeScript designed to aid static compilation likely would have that distinction. But the big elephant in the room is TypeScript’s structural subtyping. T…

Outside of really funky code, especially code originally written in TS, you can assume the interface is the actual underlying object. You could easily flag non-recognized-member accesses to interfaces and then degrade them back to object accesses.

Re: Porffor: A from-scratch experimental ahead-of-time JS engine

#20
post #13

I'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-fi…

Presumably 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.
Post reply on HN