Archive for February 20, 2018

Tuesday, February 20, 2018

Optimizing Global Constant Data Structures Using Relative References

Joe Groff (tweet):

Building a native compiler for a programming language with rich reflection? Runtime type information, method dispatch tables, and other metadata require complex data structures full of cross references between related language entities. To reduce the size, memory usage, and launch time cost of these pointer-heavy constant data structures, you can try building them out of relative references instead of pointers. Pointers are one of C’s defining features, and seemingly the simplest mechanism for building data structures, but they carry hidden costs when used in global constants, which we’ll explore in this post and look at how we can avoid them. Even if you’re not writing a compiler, understanding this optimization is a fun chance to peel back some of the mystique of C, explore a bit of the runtime machinery that makes C programs work in contemporary operating systems, and see how a compiler can make different tradeoffs when not constrained by the abstractions C provides.


The object_vtable structure here is a global constant, full of pointers to other global constants—it should be “free”, right? In reality, operating systems provide a fairly elaborate runtime environment in order to make C programs work. Data structures that contain global pointers will in fact allocate memory at program launch before even entering main(). To understand why, we need to peek behind the scenes and look at how the dynamic linker works.


One tradeoff to using relative references is that they do require slightly more generated code on average to dereference than absolute pointers, leading to small performance and code size costs.

Update (2018-02-20): McCloud recommends DYLD_PRINT_STATISTICS.

When Swift Makes You Use “throws” Instead of “rethrows”

Brent Royal-Gordon:

rethrows lets you specify that a function can only throw if one of the functions passed to it as a parameter can throw. It enforces this by only allowing try to be applied to calls to those functions or rethrows functions which are being passed those functions, and only allowing throws inside a catch block.

However, this enforcement can sometimes get in the way. For example, this function only throws if the function it is passed throws, but the compiler cannot statically prove this to itself[…]


It is possible to work around this by exploiting certain bugs in the rethrows checking—the Dispatch overlay does this to add error handling to DispatchQueue.sync(execute:)—but this is not ideal for obvious reasons.

Via Ole Begemann:

We can use the same trick for our problem. Check out the relevant code in the Swift repository. And here’s the verbatim copy of the code (I only changed the function names) for performAndWait[…]


performAndWait now calls through to a private helper function that takes two throwing functions (the original block and an error handler) and this convinces the compiler that the rethrows invariant holds.

How to Use Adaptive Width Strings for Localization

Daniel Martín:

One of the challenges of localization lies in the length of translated texts. Languages like German are especially problematic because of its longer texts compared to English. In addition to that, translators are often working with isolated strings, where the only context they get (if they get any) is the place where the string is going to be placed and its purpose, but they don’t usually have any idea about the available physical space on the screen. Moreover, the available space may not be constant as the same app may be run on an iPhone or an iPad (or even a Mac in the future?).


In order to solve this problem, if you don’t want to engineer your own solution Apple introduced “adaptive strings” with iOS 9. This feature is based on string dictionaries (.stringsdict files), which are commonly used to support pluralization rules in apps.


For each key that you want to support multiple localizations, add a NSStringVariableWidthRuleType dictionary with key/value pairs, one for each “class” of screen width that you want to support.

This relies on a private __NSVariableWidthString string subclass, which survives conversion to a Swift String, though you may need to be careful not to lose it if you manipulate the String rather than passing it directly to a control.

Christoph Mantler:

When Wordcrafts is finished with the translations, the company will push its changes in the dedicated branch, create a pull request on GitHub, and send us an email stating that everything is finished. Once this occurs, the translations go through a second process of QA — this time on our end — to ensure that all strings are correct. There are also tests in place to check whether or not the code syntax is correct.


Below is a great example of how a plural string will look when translated. The key is defined on the top, and below are all the various cases that can apply for this string (zero, one, other)[…]

Update (2019-04-10): Kuba Suder:

Looks like the i18n pluralization rules used in Cocoa “stringsdict” files are a Unicode standard - there are some nice charts here.

Security and Privacy Issues of Bitcoin

Adrian Colyer:

At the core of this survey is a catalogue of security attacks on Bitcoin, together with known defences or mitigations where applicable. We’ve touched on many of these before in one way or another, but it’s helpful to see them all in one place.

GitHub Shouldn’t Allow Username Reuse

Jesse Donat (via Hacker News):

Usernames, once deleted, should never be allowed to be valid again. Many sites including Google do it this way.

Allowing username reuse completely breaks any trust that what I pull is what it claims to be.


I think another good option would be Github offering permalinks to repos, such that if they were deleted and recreated the pathing would change.

It affects not only package managers and programs and software, but humans. Humans navigating Github. I have no way to tell while navigating the site if a project is the original or a charade. That is a problem.

Previously: Trusting SDKs.