Skip to content

Commit 30e4c58

Browse files
committed
add first draft docs
1 parent 9cdb0b5 commit 30e4c58

File tree

25 files changed

+168
-53
lines changed

25 files changed

+168
-53
lines changed

README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@ A realm for typed objects.
55

66
## What?
77

8+
## API Documentation
9+
10+
Currently very work in progress, see [src/README.md](./src/README.md).
811

912
## Installation
1013

src/README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Type Realm
2+
3+
* [Builtin Types](./builtins/README.md)
4+
* [Hash Functions](./hash-functions/README.md)
5+
* [Type Classes](./type-classes/README.md)
6+
* [String Pool](./string-pool/README.md)

src/builtins/README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Builtin Types
2+
3+
These types are builtin and always available.
4+
5+
* [T.Any](./any/README.md)
6+
* [T.Array](./array/README.md)
7+
* [T.Boolean](./boolean/README.md)
8+
* [T.Int8](./int8/README.md)
9+
* [T.Int16](./int16/README.md)
10+
* [T.Int32](./int32/README.md)
11+
* [T.Uint8](./uint8/README.md)
12+
* [T.Uint16](./uint16/README.md)
13+
* [T.Uint32](./uint32/README.md)
14+
* [T.Float32](./float32/README.md)
15+
* [T.Float64](./float64/README.md)
16+
* [T.HashMap](./hash-map/README.md)
17+
* [T.Object](./object/README.md)
18+
* [T.String](./string/README.md)
19+
* [T.InternedString](./interned-string/README.md)
20+

src/builtins/any/README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Any Type
2+
3+
`Any` can represent any kind of serializable value, (e.g. not a `Function` or `Symbol`).
4+
It takes up 12 bytes of space aligned to 8 bytes. The structure looks like this:
5+
6+
|--------------------------------------------|
7+
| Value or Pointer (Float64) |
8+
|--------------------------------------------|
9+
| Type Tag (Uint32) |
10+
----------------------------------------------
11+
12+
13+
If the value being stored can be represented in 8 bytes or less, it is stored inline, otherwise
14+
space is allocated for the value separately and a pointer is stored.

src/builtins/any/index.js

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ export function make (realm: Realm): PrimitiveType<any> {
1111
const Any = new PrimitiveType({
1212
name: 'Any',
1313
byteAlignment: 8,
14-
byteLength: 16,
14+
byteLength: 12,
1515
cast (input: any): any {
1616
if (typeof input === 'function' || typeof input === 'symbol') {
1717
throw new TypeError(`Cannot store values with type: ${typeof input}`);
@@ -36,77 +36,77 @@ export function make (realm: Realm): PrimitiveType<any> {
3636
let initialAddress;
3737
if (Type === null) {
3838
backing.setFloat64(address, 0);
39-
backing.setFloat64(address + 8, 0);
39+
backing.setUint32(address + 8, 0);
4040
}
4141
else if (Type.byteLength <= 8) {
42-
backing.setFloat64(address, Type.id);
43-
Type.initialize(backing, address + 8, initialValue);
42+
Type.initialize(backing, address, initialValue);
43+
backing.setUint32(address + 8, Type.id);
4444
}
4545
else if (initialValue[$Backing] === backing && (initialAddress = initialValue[$Address])) {
46-
backing.setFloat64(address, Type.id);
47-
backing.setFloat64(address + 8, initialAddress);
46+
backing.setFloat64(address, initialAddress);
47+
backing.setUint32(address + 8, Type.id);
4848
backing.gc.ref(initialAddress);
4949
}
5050
else {
51-
backing.setFloat64(address, Type.id);
5251
const target = backing.gc.alloc(Type.byteLength, Type.id, 1);
5352
Type.initialize(backing, target, initialValue);
54-
backing.setFloat64(address + 8, target);
53+
backing.setFloat64(address, target);
54+
backing.setUint32(address + 8, Type.id);
5555
}
5656
},
5757
store (backing: Backing, address: float64, value: any): void {
5858
const Type = realm.typeOf(value);
59-
const existingTypeId = backing.getFloat64(address);
59+
const existingTypeId = backing.getUint32(address + 8);
6060
if (existingTypeId !== 0) {
6161
const existingType = realm.I[existingTypeId];
6262

6363
if (existingType === Type && Type.byteLength <= 8) {
64-
Type.store(backing, address + 8, value);
64+
Type.store(backing, address, value);
6565
return; // nothing left to do.
6666
}
6767
else if (existingType.byteLength <= 8) {
68-
existingType.clear(backing, address + 8);
68+
existingType.clear(backing, address);
6969
}
7070
else {
71-
const pointer = backing.getFloat64(address + 8);
71+
const pointer = backing.getFloat64(address);
7272
if (pointer !== 0) {
7373
backing.gc.unref(pointer);
74-
backing.setFloat64(address + 8, 0); // ensures that the value is cleared, even if store fails.
74+
backing.setFloat64(address, 0); // ensures that the value is cleared, even if store fails.
7575
}
7676
}
7777
}
7878
let valueAddress;
7979

8080
if (Type === null) {
8181
backing.setFloat64(address, 0);
82-
backing.setFloat64(address + 8, 0);
82+
backing.setUint32(address + 8, 0);
8383
}
8484
else if (Type.byteLength <= 8) {
85-
backing.setFloat64(address, Type.id);
86-
Type.initialize(backing, address + 8, value);
85+
Type.initialize(backing, address, value);
86+
backing.setUint32(address + 8, Type.id);
8787
}
8888
else if (value[$Backing] === backing && (valueAddress = value[$Address])) {
89-
backing.setFloat64(address, Type.id);
90-
backing.setFloat64(address + 8, valueAddress);
89+
backing.setFloat64(address, valueAddress);
90+
backing.setUint32(address + 8, Type.id);
9191
backing.gc.ref(valueAddress);
9292
}
9393
else {
94-
backing.setFloat64(address, Type.id);
9594
const target = backing.gc.alloc(Type.byteLength, Type.id, 1);
9695
Type.initialize(backing, target, value);
97-
backing.setFloat64(address + 8, target);
96+
backing.setFloat64(address, target);
97+
backing.setUint32(address + 8, Type.id);
9898
}
9999
},
100100
load (backing: Backing, address: float64): any {
101-
const typeId = backing.getFloat64(address);
101+
const typeId = backing.getUint32(address + 8);
102102
if (typeId === 0) {
103103
return null;
104104
}
105105
const Type = realm.I[typeId];
106106
if (Type.byteLength <= 8) {
107-
return Type.load(backing, address + 8);
107+
return Type.load(backing, address);
108108
}
109-
const pointer = backing.getFloat64(address + 8);
109+
const pointer = backing.getFloat64(address);
110110
assert: pointer > 0;
111111
return Type.load(backing, pointer);
112112
},

src/builtins/array/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Array Type
2+
3+
The generic array type, can contain [any](../any/README.md) serializable value.
4+

src/builtins/boolean/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Boolean Type
2+
3+
Represents boolean values, takes up a single byte, no alignment.

src/builtins/float32/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Float32 Type
2+
3+
Represents 32 bit floating point numbers. Takes up 4 bytes, aligned to 4 bytes.

src/builtins/float64/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Float64 Type
2+
3+
Represents 64 bit floating point numbers, allowing integers of up to 53 bits to be stored safely.
4+
Takes up 8 bytes aligned to 8 bytes.

src/builtins/hash-map/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Hash Map
2+
3+
Generic hash map type allowing [any](../any/README.md) serialiable input as key / value.
4+
5+
```js
6+
const map = new T.HashMap();
7+
8+
map.set('hello', 'world');
9+
map.set(123, 456);
10+
map.set(true, false);
11+
12+
console.log(map.get('hello'));
13+
console.log(map.get(123));
14+
console.log(map.get(true));
15+
```

src/builtins/int16/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Int16
2+
3+
Represents a 16 bit integer value. Takes up 2 bytes, aligned to 2 bytes.

src/builtins/int32/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Int32
2+
3+
Represents a 32 bit integer value. Takes up 4 bytes, aligned to 4 bytes.

src/builtins/int8/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Int8
2+
3+
Represents a 8 bit integer value. Takes up 1 byte, no alignment.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Interned String Type
2+
3+
Interned strings are stored in a [pool](../../string-pool/README.md), ensuring that a copy of any particular string is stored only once, and all further attempts to store the same string will return the existing copy's address.
4+
5+
Interned strings offer memory savings and faster exact comparisons compared to normal strings, at the expense of greater CPU usage when they are first created.
6+
7+
Structurally they share a similar implementation to the normal [String](../string/README.md) type.
8+
9+
Note that the number of strings that can be interned in total is constrained by the arena size. See the [string pool documentation](../../string-pool/README.md) for more information.

src/builtins/object/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Object Type
2+
3+
Represents simple objects.

src/builtins/string/README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# String Type
2+
3+
Strings are length-and-hash-prefixed arrays of characters.
4+
If the string is ascii compatible, each character is a Uint8 occupying a single byte.
5+
If the string contains non-ascii characters, each character in the string is a Uint16, occupying two bytes.
6+
To determine which type of string we're dealing with, we store a negative length for Uint16 arrays and a positive length for Uint8 arrays.
7+
The length always refers to the array length and therefore the number of characters, rather than the number of bytes.
8+
9+
Strings layout:
10+
11+
---------------------------------------------
12+
| Length: Int32 | (If length is negative, the string is a Uint16 array.)
13+
---------------------------------------------
14+
| Hash: Uint32 |
15+
---------------------------------------------
16+
| Data: Uint8[](Length)|Uint16[](Length) |
17+
---------------------------------------------
18+
19+
Because they have dynamic lengths, strings are always stored by reference.

src/builtins/string/index.js

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,6 @@ export const STRING_DATA_OFFSET = STRING_HEADER_SIZE;
1313

1414
/**
1515
* Make a simple string type for the given realm.
16-
*
17-
* Strings are length-and-hash-prefixed arrays of characters.
18-
* If the string is ascii compatible, each character is a Uint8 occupying a single byte.
19-
* If the string contains non-ascii characters, each character in the string is a Uint16, occupying two bytes.
20-
* To determine which type of string we're dealing with, we store a negative length for Uint16 arrays and a positive length for Uint8 arrays.
21-
* The length always refers to the array length and therefore the number of characters, rather than the number of bytes.
22-
*
23-
* Strings layout:
24-
*
25-
* ---------------------------------------------
26-
* | Length: Int32 | (If length is negative, the string is a Uint16 array.)
27-
* ---------------------------------------------
28-
* | Hash: Uint32 |
29-
* ---------------------------------------------
30-
* | Data: Uint8[](Length)|Uint16[](Length) |
31-
* ---------------------------------------------
32-
*
33-
*
3416
*/
3517
export function make (realm: Realm): PrimitiveType<string> {
3618
const {StringType} = realm;

src/builtins/uint16/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Uint16
2+
3+
Represents an unsigned 16 bit integer value. Takes up 2 bytes, aligned to 2 bytes.

src/builtins/uint32/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Uint32
2+
3+
Represents an unsigned 32 bit integer value. Takes up 4 bytes, aligned to 4 bytes.

src/builtins/uint8/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Uint8
2+
3+
Represents an unsigned 8 bit integer value. Takes up 1 byte, no alignment.

src/hash-functions/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Hash Functions
2+
3+
Hash functions take certain kinds of input and return an unsigned 32 bit numeric hash which identifies the input.

src/random/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Random Value Generators
2+
3+
The functions in here generate certain kinds of random value.

src/string-pool/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# String Pool
2+
3+
Holds a list of [interned strings](../builtins/interned-string/README.md).

src/type-class/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Type Classes
2+
3+
Type classes represent categories of type. Each type class is assigned a range of possible ids, and each instantiation of a type class (a Type), has an id within that range.

0 commit comments

Comments
 (0)