HN user

wingo

1,533 karma

http://wingolog.org/

Posts42
Comments335
View on HN
wingolog.org 3y ago

Structure and Interpretation of Ark

wingo
1pts0
wingolog.org 13y ago

Localhost port scanner

wingo
1pts0
lcamtuf.coredump.cx 14y ago

Postcards from the post-XSS world

wingo
3pts0
wingolog.org 14y ago

Inline cache applications in Scheme

wingo
7pts0
packetlife.net 14y ago

TCP Slow Start

wingo
4pts0
wingolog.org 14y ago

Unexpected Concurrency

wingo
2pts0
wingolog.org 14y ago

Eval, That Spectral Hound

wingo
7pts0
areyoubitteraboutit.com 14y ago

Are you bitter about it?

wingo
3pts0
wingolog.org 14y ago

Partial Evaluation in Guile

wingo
5pts0
wingolog.org 14y ago

A Closer Look at Crankshaft, V8's Optimizing Compiler

wingo
21pts4
wingolog.org 15y ago

SSA and the Lambda Tribe

wingo
94pts8
www.opencobol.org 15y ago

Extending COBOL with Scheme and Brainfuck

wingo
16pts3
wingolog.org 15y ago

Guile 2.0.2: Building the Guildhall

wingo
54pts13
walfield.org 15y ago

Lambdas in C

wingo
111pts38
wingolog.org 15y ago

V8 is faster than GCC

wingo
68pts24
wingolog.org 15y ago

What does V8 do with that loop?

wingo
8pts0
wingolog.org 15y ago

Value Representation in JavaScript Implementations

wingo
3pts0
kernelnewbies.org 15y ago

Linux 2.6.28: autogrouping, faster dcache, transparent hugepages

wingo
2pts0
www.bufferbloat.net 15y ago

Bufferbloat

wingo
4pts0
wingolog.org 15y ago

Types and the Web

wingo
2pts0
www.scsh.net 15y ago

"Who should I thank?"

wingo
2pts0
zguide.zeromq.org 15y ago

11 Likely Problems In Your Multithreaded Code

wingo
2pts0
www.xml.com 15y ago

XML on the Web is Dead (2004)

wingo
1pts0
en.wikipedia.org 15y ago

Emoji

wingo
1pts0
www.varnish-cache.org 15y ago

What's wrong with 1975 programming?

wingo
41pts12
wingolog.org 15y ago

Abusing the C Compiler

wingo
40pts19
www.pvk.ca 16y ago

There's more to locality than caches

wingo
5pts0
vanemden.wordpress.com 16y ago

Interview with Alan Robinson, inventor of resolution logic

wingo
5pts1
www.untyped.com 16y ago

Formalising Bonds with the Informal

wingo
6pts0
cseweb.ucsd.edu 16y ago

Return-into-libc without Function Calls

wingo
4pts0

That's certainly the case for full CPS, but using a CPS intermediate language does not imply call/cc. Indeed Kennedy targeted the .Net CIL; a direct-style VM. The important thing to note is that continuations and functions can be statically distinguished. The article conflates the two, which is why I don't find it very useful.

Boot-to-Guile 13 years ago

AFAIUI libc is in the initrd, but it's a statically linked libc. Guile's dynamic FFI uses dlopen/dlsym to get its function pointers, so it can't do that in a statically linked libc. (Or could it? I suppose there's no reason why a statically linked library wouldn't expose symbol tables, whether via dlsym or some other means.)

Your point about size is well-taken though. Besides libc in this case, Guile's build products are much larger (and slower) than LuaJIT's images because we've been trying to write the compiler in Scheme from the very beginning. We can't even think about doing a nice JIT until we have a good AOT compiler, because otherwise the JIT written in Scheme would be too slow.

You can redirect the control-flow of the program by overwriting a return address or a vtable. Once you've done that, it's easiest if you can redirect control to code you've written, in executable heap; but if that's not possible, you can still use return-to-libc, or potentially "return-oriented programming" strategies.

Sounds like your problem is more that Scheme is too small for the programs you'd like to write. Implementations that are adequate to your needs being incompatible with each other is a natural side effect.

The new standard will help marginally, but there will be no grand unification of Schemes. R6RS was big enough for your needs but did not achieve wide adoption. There is no fundamental reason why this would be different for the larger R7RS report (on which work has not yet begun). Indeed, some implementations have already forked with an explicit intention of going on their own paths (Racket).

In short, for serious work, you might be able to share modules between implementations if that matters to you, but your overall application will be implementation-specific.

FWIW, IMHO, etc...

An interesting perspective here:

"MCNP is written in the style of Dr. Thomas N. K. Godfrey, the principal MCNP programmer from 1975-1989 ... All variables local to a routine are no more than two characters in length, and all COMMON variables are between three and six characters in length ... The principal characteristic of Tom Godfrey's style is its terseness. Everything is accomplished in as few lines of code as possible. Thus MCNP does more than some other codes that are more than ten times larger. It was Godfrey's philosophy that anyone can understand code at the highest level by making a flow chart and anyone can understand code at the lowest level (one FORTRAN line); it is the intermediate level that is most difficult. Consequently, by using a terse programming style, subroutines could fit within a few pages and be most easily understood. Tom Godfrey's style is clearly counter to modern computer science programming philosophies, but it has served MCNP well and is preserved to provide stylistic consistency throughout."

This from MCNP4c chapter 2, section B, quoted here: http://wingolog.org/archives/2005/04/09/101. Alas, the link in that article is dead.

FWIW, I neither agree nor disagree with Godfrey's style.

Well, I guess the one thing I would correct is the "why". The LLInt doesn't just produce assembler to be fast, though it is faster than the old interpreter. The real reason it produces assembler is to control the stack representation, so that it works better with tiering, exceptions, and the optimizing compiler (DFG). Otherwise, interpreting was a lose, because tiering up cost too much.

As you can see, the situation is a bit complicated. If I could have made the article shorter, I would have :)

No offense intended, but this comment does not add very much while misunderstanding some other things. For example, I did not write the LLInt. It was mostly written by Apple's Filip Pizlo.

If this is the sort of topic you are interested in, then you can have the patience to read a few paragraphs. If it's not, then summarizing isn't going to help :)

How does such a touching, honest article get such terrible comments? (Referring to the comments on the author's blog.)

In any case I don't see why anyone would allow such lampreys to suck the life of their own web page.

I look forward to seeing articles on Moore's work; I did not have the pleasure of knowing him.

In the meantime, this headline had me a little confused, thinking of the chip designer Chuck Moore who was Forth's creator. It doesn't seem that this is the same Moore. Just FYI :)

Lisp Machines 14 years ago

Much love for lisp machines, but stack machines do not offer any performance advantages over register machines, and actually make optimization much harder. See Ungar's 1993 thesis on the Self 93 compiler for an early realization of this, where he examines what microcode / register windows / etc could do for him, and how he was able to do just as well with registers.

Dunno, Paul. While SPJ does have a lot of relevance to current computing, his work is not a product like Etherpad was. I haven't seen YC companies moving towards or staying with fringe languages -- not that I criticize that business decision.

Maybe the YC model will reach that "how will we be computing in 10 years" phase at some point. But (perhaps with good reason?) it does not seem to be there yet.

Lovely article!

I wonder though, how do you know that is parsing time? There are a number of things happening when JS is loaded, and parsing is only one of them.

Also, an update on that article would probably be useful -- a number of things have changed in the major browsers since you wrote it.

Happy hacking :)

Parsing is not the slow part.

Fetching js over the net is slow (multiple orders of magnitude slower than parsing).

Optimized compilation is slow (an order of magnitude).

But you can't even do baseline compilation without knowing what's in your evironment. For example, JSC (from WebKit) compiles to bytecode. But the compilation process happens lazily, as functions are first executed. (There is a quick pass to check syntax, beforehand. V8 does this too AFAIR.)

But OK, let's say you're parsing. You parse, create an AST, and go to compile it. The result of bytecompiling for V8 is native code! You can't cache that effectively, it will embed too many runtime constants. For JSC you do produce bytecode, but that bytecode too is dependent on runtime object layouts: for example if you reference a binding in the global object, and the binding is present, then the compiler will produced an indexed lookup into the global. That depends on what's in the global when the compilation unit (function, eval, or global code) is compiled. Caching is a security / correctness risk, in that context.

And then you have the negative impacts of caches on browser memory footprint (and associated GC cost).

It's no wonder why modern JS engines prefer to just keep around the source, and re-parse on demand.