The Invalid 68030 Instruction That Allowed the Macintosh Classic II to BootPermalink

Doug Brown:

This is the story of how Apple made a mistake in the ROM of the Macintosh Classic II that probably should have prevented it from booting, but instead, miraculously, its Motorola MC68030 CPU accidentally prevented a crash and saved the day by executing an undefined instruction.

Incredible that we’re still discovering things about these machines some 30 years later. Doug dives deep to work out why MAME was unable to emulate the Macintosh Classic II.

Things People Get Wrong About ElectronPermalink

Felix Rieseberg:

I dedicated years bringing web technologies and desktop apps closer together. The most recent and most successful project in that vein is Electron, which I’ve spent the last ten years working on.

As an open source project, our website never had to “convince people” to use Electron, so I never took the time to actually explain why I’m betting on web technologies to build user interfaces or why I prefer bundling a rendering engine.

Electron’s choices, especially the very idea of building interfaces with web tech and shipping large parts of Chromium to render them, are not uncontroversial. Reasonable people wonder why we made those choices.

I finally took the time to write down the arguments for the choices that we made. You can find that document on the Electron homepage. It tries to pre-empt a lot of common misconceptions. This post is a pairing suggestion—and discusses some of the things I believe people get most wrong about Electron on the Internet today.

I’ll admit I’m not a huge Electron fan. Slack’s early years soured me on it considerably. Back then it would regularly use 2Gb or more of RAM, which was outrageous on a contemporary machine with 8Gb of RAM.

Nowadays Electron apps are somewhat unavoidable, and seem to be a bit better behaved. Still, there’s no standard UI across Electron apps, and each one bringing 100Mb or more of Chromium along for the ride1 does not fill me with joy. Ultimately, Electron feels like a tool that’s good for business, not a tool for building amazing applications.

Nonetheless it’s interesting to read this perspective on Electron from one of its developers. I certainly don’t agree with some of the arguments though:

Electron pits JavaScript versus native code

The argument: JavaScript isn’t the right choice for everything. Native is better. Electron is not native.

This misconception is likely the fault of Electron’s maintainer team and especially me. Most of the talks I’ve given in the earlier days of Electron highlighted its ability to interact with the operating system from JavaScript.

However, the entire point of Electron is that you can pair your web app with any native code you want to write—specifically with C++, Objective-C, or Rust.

I don’t think that point is well advertised or a reflection of Electron use in practice. From my experience most Electron apps use JavaScript and web technologies as much as possible, only using native code if absolutely necessary. In contrast Tauri seems to emphasise the native back-end aspect of their implementation quite a bit more. Right on their home page they say:

Write your frontend in JavaScript, application logic in Rust, and integrate deep into the system with Swift and Kotlin.

Whereas the only similar thing on the Electron home page is:

Native graphical user interfaces

Interact with your operating system’s interfaces with Electron’s main process APIs. Customize your application window appearance, control application menus, or alert users through dialogs or notifications.

The APIs that it’s talking about are JavaScript APIs… so that you can stay in JS land and not have to write native code.

Most Electron apps clock in around 100 to 300 MB. From first principles, smaller is obviously better. Nobody argues that a bigger app is better than a smaller app.

But: Users, both in the consumer and business space, do not care. One hour of Netflix at 4K is roughly 7 GB, a typical Call of Duty update regularly clocks in more than 300 GB. In practice, we have not seen end users care about binary size more than they do about virtually anything else your engineering team could spend time on.

This feels like its coming from an incredibly privileged and sheltered viewpoint. I’m sure there are plenty of places in the world where people do care a lot about downloads clocking in at hundreds of megabytes. No doubt there’s a bunch of them here in Australia—my parents still have a 12MBit connection. Additionally, there’s a big difference between ephemeral downloads for streaming and downloads that permanently take up space on your hard disk (multiplied by every Electron app you have installed).

  1. Kudos to the heroic efforts of the Arch Linux packagers who package Electron apps with a dependency on a shared Electron runtime. You still end up with multiple versions of those runtime packages (such as electron28 and electron30), but at least there’s only one copy of each version, and updates to the dependant apps are much smaller.

Tracking Down a Rogue EINVAL Error in FirmwarePermalink

Dion Dokter writing on the Tweede golf blog about what must have been an incredibly frustrating bug:

We had not gotten further in a long time. At this point, we had already spent around 20 days on this issue collectively and we had no clear direction to go in. Maybe we could take a more brute-force approach, but that was infeasible due to the modem jail.

Why was the RPC call made with length 0 and a null pointer?

We tried using watchpoints at the start of the adventure, but not all hardware supports it. So when we didn’t get it to work, we assumed this microcontroller also had no support for it. But simply updating the debugging stack to the newest versions did the trick. So if you’re ever debugging something and the experience is kind of bad, then make sure to download the newest versions! Even when that means going outside of your OS package manager.

Once Wouter got things going, the whole debugging experience became much nicer.

Things went fast from here. He was able to find where exactly the rpc length was written. He noticed that the length was lowered from the 44 input to the function to 0. Why?

It’s a long read but they did track down the source of the bug in the end.

Posts like this can be good to keep in the back of your mind whenever you’re tackling a gnarly bug. Perhaps there’s an insight here that would help shortcut the process if you ever find yourself in a similar position.

Branchless UTF-8 DecodingPermalink

Charles Eckman:

In a Recurse chat, Nathan Goldbaum asked:

I know how to decode UTF-8 using bitmath and some LUTs (see https://github.com/skeeto/branchless-utf8), but if I want to to go from a codepoint to UTF-8, is there a way to do it without branches?

To start with, is there a way to write this C function, which returns the number of bytes needed to store the UTF-8 bytes for the codepoint without any branches? Or would I need a huge look-up-table?

A neat problem to explore.

No if statements, loops, or other conditionals. So, branchless, right?

…well, no. If we peek at the (optimized) code in Compiler Explorer, we can see the x86_64 assembly has two different kinds of branches.

I tinkered with this initial implementation a little. If you compile it with target-cpu=x86-64-v3 (circa 2013 CPUs) the test and je from leading_zeros call are eliminated, leaving just the bounds check ja.

Using the Rust Type System to Prevent Bugs in the Fuchsia Network StackPermalink

Daroc Alden at LWN covering Joshua Liebow-Feeser at RustConf:

Netstack3 encompasses 63 crates and 60 developer-years of code. It contains more code than the top ten crates on crates.io combined. Over the last year, the code has finally become ready to deploy. But deploying it to production requires care — networking code can be hard to test, and the developers have to assume it has bugs. For the past eleven months, they have been running the new networking stack on 60 devices, full time. In that time, Liebow-Feeser said, most code would have been expected to show “mountains of bugs”. Netstack3 had only three; he attributed that low number to the team’s approach of encoding as many important invariants in the type system as possible.

A remarkable result. Great to see signs that Fuchsia is still alive too.