97 lines
3.1 KiB
Markdown
97 lines
3.1 KiB
Markdown
---
|
|
title: "Value Representation"
|
|
description: "JSValue tagging and encoding"
|
|
---
|
|
|
|
## Overview
|
|
|
|
Every value in ƿit is a 64-bit word called a JSValue. The runtime uses LSB (least significant bit) tagging to pack type information directly into the value, avoiding heap allocation for common types.
|
|
|
|
## Tag Encoding
|
|
|
|
The lowest bits of a JSValue determine its type:
|
|
|
|
| LSB Pattern | Type | Payload |
|
|
|-------------|------|---------|
|
|
| `xxxxxxx0` | Integer | 31-bit signed integer in upper bits |
|
|
| `xxxxx001` | Pointer | 61-bit aligned heap pointer |
|
|
| `xxxxx101` | Short float | 8-bit exponent + 52-bit mantissa |
|
|
| `xxxxx011` | Special | 5-bit tag selects subtype |
|
|
|
|
### Integers
|
|
|
|
If the least significant bit is 0, the value is an immediate 31-bit signed integer. The integer is stored in the upper bits, extracted via `v >> 1`.
|
|
|
|
```
|
|
[integer: 31 bits][0]
|
|
```
|
|
|
|
Range: -1073741824 to 1073741823. Numbers outside this range are stored as short floats or heap-allocated.
|
|
|
|
### Pointers
|
|
|
|
If the lowest 3 bits are `001`, the value is a pointer to a heap object. The pointer is 8-byte aligned, so the low 3 bits are available for the tag. The actual address is extracted by clearing the low 3 bits.
|
|
|
|
```
|
|
[pointer: 61 bits][001]
|
|
```
|
|
|
|
All heap objects (arrays, records, blobs, text, functions, etc.) are referenced through pointer-tagged JSValues.
|
|
|
|
### Short Floats
|
|
|
|
If the lowest 3 bits are `101`, the value encodes a floating-point number directly. The format uses an 8-bit exponent (bias 127) and 52-bit mantissa, similar to IEEE 754 but with reduced range.
|
|
|
|
```
|
|
[sign: 1][exponent: 8][mantissa: 52][101]
|
|
```
|
|
|
|
Range: approximately ±3.4 * 10^38. Numbers outside this range fall back to null. Zero is always positive zero.
|
|
|
|
### Specials
|
|
|
|
If the lowest 2 bits are `11`, the next 3 bits select a special type:
|
|
|
|
| 5-bit Tag | Value |
|
|
|-----------|-------|
|
|
| `00011` | Boolean (true/false in upper bits) |
|
|
| `00111` | Null |
|
|
| `01111` | Exception marker |
|
|
| `10111` | Uninitialized |
|
|
| `11011` | Immediate string |
|
|
| `11111` | Catch offset |
|
|
|
|
## Immediate Strings
|
|
|
|
Short ASCII strings (up to 7 characters) are packed directly into the JSValue without heap allocation:
|
|
|
|
```
|
|
[char6][char5][char4][char3][char2][char1][char0][length: 3][11011]
|
|
```
|
|
|
|
Each character occupies 8 bits. The length (0-7) is stored in bits 5-7. Only ASCII characters (0-127) qualify — any non-ASCII character forces heap allocation.
|
|
|
|
```javascript
|
|
var s = "hello" // 5 chars, fits in immediate string
|
|
var t = "" // immediate (length 0)
|
|
var u = "longtext" // 8 chars, heap-allocated
|
|
```
|
|
|
|
## Null
|
|
|
|
Null is encoded as a special-tagged value with tag `00111`. There is no `undefined` in ƿit — only null.
|
|
|
|
```javascript
|
|
var x = null // special tag null
|
|
var y = 1 / 0 // also null (division by zero)
|
|
var z = {}.missing // null (missing field)
|
|
```
|
|
|
|
## Boolean
|
|
|
|
True and false are encoded as specials with tag `00011`, distinguished by a bit in the upper payload.
|
|
|
|
## Summary
|
|
|
|
The tagging scheme ensures that the most common values — small integers, booleans, null, and short strings — require zero heap allocation. This significantly reduces GC pressure and improves cache locality.
|