Skip to content

A demonstration of NaN boxing for runtime type checking

Notifications You must be signed in to change notification settings

AveryBurke/nan_boxing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NaN Boxing Demo

This is a simple demonstration of the NaN Boxing implementation described in my blog post Dynamic Typing and NaN Boxing.

NaN boxing is an optimization in dynamically typed languages to store the type and the value of a token, together, by exploiting some features of the IEEE specification for NaN. It turns out the specification leaves 51 mantissa bits that get ignored when a double is determined to be Not a Number. NaN boxing works by storing the type and the value in those overlooked bits. This avoids allocating doubles on the heap and it preserves locality of reference.

I use the three most significant digits of the 51 mantissa bits to store type data. The three bit type data is also referred to as a tag. The remaining 48 digits store the value data. I will refer to this as the payload. Since modern architectures only use the lower 48 bits of a 64 bit pointer, the payload can even hold pointers.

Features

This implementation supports three types: float, int and string. The repl will try to first parse a float, if successful it will test if the float can be represented as a 32 bit int. Otherwise it will treat the token as a string.

Floats

With NaN boxing you get floats for free. So if a token can be parsed as a float nothing more needs to be done.

Ints

This implementation uses 32 bit ints. An int is encoded by tagging a NaN as an int and directly encoding the int’s bits into the payload. An int is decoded by masking the 32 bits from the tagged NaN, truncating the masked payload and casting the result as an int32_t.

strings

A parsed string is first copied to the heap. Then a pointer to the new address is encoded into a tagged NaN. Strings are decoded by masking the 48 bit payload and casting the result to a char pointer

Dependencies

You will need just installed if you want to build and test the project. You can also simply run the REPL from the binary

Usage

Start the REPL with ./repl or with just run. Enter expressions and watch as they are evaluated right before your eyes!

$> (+ 8 -8 .1234)
type: string, value: (
type: string, value: +
type: int, value: 8
type: int, value: -8
type: float, value: 0.123400
type: string, value: )

Run tests with just test.

About

A demonstration of NaN boxing for runtime type checking

Topics

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published