HNHacker News
TopNewBestAskShowJobs

ofubd8kc

55 karma · joined June 15, 2021

submissionscomments
ofubd8kc··on A bare metal physical implementation of WASM. That's right, a WebAssembly CPU (2018)
> What you are showing is not a purebred stack machine

I see where you are coming from now, and yes, you are correct these stack CPUs are not pure. The whole point though of trying to do a stack machine CPU (however impure) is to simplify register allocation, which is why the 1982 C Machine Stack Cache paper I cited has a title beginning with Register Allocation for Free.... Whether writing a compiler or writing assembler by hand, at some point you hit the problem that it's not easy to fit all your variables into registers r0 through r15 (or whatever) and you must then spill them onto the stack. You evidently have first-hand experience with the challenges of keeping performance critical variables in registers. So the essence of these stack processors, the whole point of trying to build them, is to just let you spill everything on the stack and let the CPU worry about how to map stack locations to fast registers.

Excerpt from the C Machine Stack Cache paper[1]:

The goal of the Stack Cache is to keep the top elements of the stack in high speed registers. The problem we solve is how to perform the allocation of these registers without placing the burden on the compiler, and at the same time retaining the efficiency of register accesses. Control of the hardware, the instruction set, and a disciplined use of the aforementioned calling sequence allows a memory-to-memory style architecture (i.e. registerless to the compiler) to perform an automatic binding of memory addresses to machine registers.

[1] https://www.eecg.utoronto.ca/~jzhu/csc467/readings/ra-for-fr...

ofubd8kc··on A bare metal physical implementation of WASM. That's right, a WebAssembly CPU (2018)
From the programmer's perspective C is not a stack based language the way that, say, Forth is, because (as you note) there are no explicit push and pop instructions. But from an implementor's perspective, evaluating C function calls and arithmetic expressions is very stack oriented, which is why in the cited paper some Bell Labs researchers in the early 1980s were trying to build stack machine CPUs to execute C code. Given your Lisp experience, just think about how you'd translate various C expressions to Lisp ones, and how Lisp expressions map to stack operations, and you'll see C's stack based nature come out. (I.e. the abstract syntax trees (ASTs) a C compiler builds can naturally be represented as Lisp-like expressions.)

C:

  y = a*x + foo(b);
Lisp:

  (setq y (+ (* a x) (foo b)))
Example stack instructions for the above (many variations possible):

  PUSH a
  PUSH x
  MUL
  PUSH b
  PUSH foo
  CALL
  ADD
  PUSH y
  SETQ  ; or MOV or whatever your arch wants to call it
Dennis Ritchie added the register storage qualifier keyword to primeval C (and also auto, inherited from B) to make the earliest C compilers easier to write, because bug-free register allocation is a very hard problem and Ritchie's earliest PDP had only a few kilobytes of core to hold both the C compiler's code and the chunk of program text being currently translated, so a complicated register allocator was out of the question.
ofubd8kc··on A bare metal physical implementation of WASM. That's right, a WebAssembly CPU (2018)
A stack-based WASM CPU for stack-based WASM bytecode will be slower than a traditional register based CPU for reasons that have been known at least since the 1970s-1980s, when stack-based CPUs for Smalltalk, Lisp, and C were tried.

This didn't stop Sun from trying again in the 1990s to make stack based CPUs for the JVM (picoJava, UltraJava, ...).

TL;DR: A WASM CPU will need a complicated stack cache to map stack positions to registers. This will involve more transistors, power, and latency than just letting compiler writers use the registers directly.

One of the earliest important papers is from 1982: "Register Allocation for Free: The C Machine Stack Cache."[1]

Lispers sometimes lament that current processors are 'C machines ill-suited to Lisp like the Symbolics Lisp processors of yore', but in reality, C is very much a stack language, too. A C compiler is soooooo much easier to write if you don't have to worry about register allocation, a hard problem.

I like that WASM is stack-based because it makes compilers for WASM much easier to write. But it makes the WASM JIT compiler much more complicated to write. But it's better that top talent at Google, Mozilla, etc. does the WASM JIT compiler so that the rest of us can focus on solving other problems.

The Lisp Machines of yore had instructions for tagged arithmetic, which can speed up, say, adding two dynamically typed variables. No need for a compiler to infer and enforce the datatypes of simple variables in advance, the processor checks the datatypes while it is executing the code and signals a type error if you try to add a float to a character. But modern JIT strategies, which can infer the datatypes of loop variables and emit native instructions lightning fast, might ultimately be better.

[1] https://www.eecg.utoronto.ca/~jzhu/csc467/readings/ra-for-fr...

ofubd8kc··on Nasty Linux systemd root level security bug revealed and patched
> The lines of code relevant to only the init are in src/core, so your comparison would probably only make sense if you compared that folder

  $ wc `find src/core \( -name \*.c -o -name \*.h \) -print`
  [...]
      81604  249802 3001043 total
So 81,604 lines for src/core vs 17,263 for OpenRC. So why does systemd need 677,446 lines of C code in its entire tree if src/core is 81,604 lines?

I suppose the answer is that IBM/Red Hat make money shipping systems that they and they alone have the expertise to support and fix. Making systemd's tree over 600k lines so that Red Hat employee Lennart is pretty much the only human being alive who understands it all is conducive to that goal.

ofubd8kc··on Nasty Linux systemd root level security bug revealed and patched
Until formal verification becomes common, something the size of systemd is always going to have security bugs that intelligence agencies will know about before the rest of us. If you don't want North Koreans hacking your server you would do better to opt for non-systemd.
ofubd8kc··on Nasty Linux systemd root level security bug revealed and patched
Why does systemd need an optional network manager? Will this optional network manager become non-optional in the future?
ofubd8kc··on Nasty Linux systemd root level security bug revealed and patched
I compared systemd vs. OpenRC code size in another post, but here is Musl vs glibc code size:

  $ git clone git://git.musl-libc.org/musl; cd musl
  $ wc `find . \( -name \*.c -o -name \*.h \) -print`
    [...]
        7      11      94 ./src/unistd/_exit.c
    104637  330017 2883975 total

  $ git clone https://sourceware.org/git/glibc.git; cd glibc
  $ wc `find . \( -name \*.c -o -name \*.h \) -print`
    [...]
        49      216     1647 ./wctype/wctype_l.c
   1389414  6823487 52867225 total
So 104,637 lines vs 1,389,414 lines. There are more human programmers on this planet who can audit 104,637 lines than can audit 1,389,414 lines. What is glibc doing that is so terribly useful that it needs to be 13 times the size of Musl? It's just standard GNU bloat. And why does GNU awk (gawk) need to add network socket programming support? Isn't this beyond the scope of what awk does well and does best? Keep adding features, keep increasing the attack surface....
ofubd8kc··on Nasty Linux systemd root level security bug revealed and patched
For many of us, our biggest beef with systemd is that it has no planned limitations to its scope. (This has already been discussed to death so I will try to be brief.) Let's look at the actual current code size. I just cloned the systemd Github repo (git clone https://github.com/systemd/systemd.git) and this is what I got:

    $ wc `find . \( -name \*.c -o -name \*.h \) -print`
    [ ... ]
            37       89     1100 ./src/xdg-autostart-generator/xdg-autostart-service.h
    677446  2077830 23953433 total
(Simple wc includes blank lines and comment lines and we could be fancier but wc will do.) Now compare the same thing with OpenRC (git clone https://github.com/OpenRC/openrc):

   $ wc `find . \( -name \*.c -o -name \*.h \) -print`
    [ ... ]
      56    242   2209 ./src/rc/_usage.h
   17263  53243 419162 total
So 677,446 lines vs. 17,263 lines.

Lennart just keeps adding to systemd and refuses to say when he will finally stop adding to it. How many skilled humans on this planet are available to audit those 600k+ lines of systemd code and are actually auditing it? (And how many work for intelligence agencies?)

ofubd8kc··on Nasty Linux systemd root level security bug revealed and patched
Just about my favorite thing about using Ubuntu on Windows via WSL is that it does not use systemd: it uses a minimalist systemd shim instead that implements enough of systemd's interfaces to keep other essential dependencies working. So on WSL Ubuntu you have init for PID 1:

  $ ps aux
  USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
  root         1  0.0  0.0   9952   764 ?        Ssl  Jun15   1:06 /init
I'm sick of Microsoft telemetry and I would like to go back to native Linux, but non-systemd options are very limited:

- Devuan is most promising, being 'Debian without systemd', but the project has mountains of work to do and few volunteers to do it, yet so far seems to be managing. I'll be keeping my eye on Devuan....

- Alpine Linux doesn't have glibc, which is a very good thing except that so many precompiled Linux binaries depend on glibc, so you are stuck doing time consuming builds for some programs you will need.

- Gentoo and Artix are rolling releases, so no long term 'you only need security updates' option for servers that just need to do one job and do it well.

EDIT: I wrote Arch instead of Artix, as a commenter below pointed out. Artix is basically Arch without systemd.

ofubd8kc··on Windows 11 screenshots leak, show new Start menu and more
The classic Win 95 bottom left Start button location has the advantage of being an 'infinite mouse target': rapidly flicking the mouse down-left always gets you there instantly because you can't overshoot the target, nor can you miss, neither to the left nor to the right. With the new centered placement you now must perform a slower aiming task.