-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathslots.ts
More file actions
57 lines (51 loc) · 2.71 KB
/
slots.ts
File metadata and controls
57 lines (51 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/**
* @file Internal-slot machinery for Temporal objects. The TC39 Temporal spec
* models per-object state as non-introspectable internal slots —
* `[[InitializedTemporalInstant]]`, `[[Nanoseconds]]`,
* `[[InitializedTemporalDuration]]`, etc. Slots are not observable via
* property access, `Reflect`, or iteration. Slot presence is the spec's
* identity check, distinct from `instanceof` (which coincides on
* freshly-constructed instances but diverges under
* `Object.create(C.prototype)`, where instanceof passes but slots are
* absent). One `WeakMap` per slot, or `WeakSet` for boolean presence.
* Receiver is the key. `WeakMap` semantics keep slot storage out of the GC
* graph, matching the spec's "internal slot" wording. Spec reference:
* https://tc39.es/proposal-temporal/ — search for
* `[[InitializedTemporalInstant]]` and `RequireInternalSlot`. Reference impl:
* js-temporal/temporal-polyfill `lib/slots.ts` (pinned commit in README.md).
*/
import { WeakMapCtor, WeakSetCtor } from '../primordials/map-set'
// ─────────────────────────────────────────────────────────────────
// Temporal.Instant slots
// https://tc39.es/proposal-temporal/#sec-properties-of-temporal-instant-instances
//
// Every Temporal.Instant instance has:
// [[InitializedTemporalInstant]] — presence sentinel
// [[Nanoseconds]] — BigInt nanoseconds since
// 1970-01-01T00:00:00Z; integral
// ─────────────────────────────────────────────────────────────────
const initializedInstant = new WeakSetCtor<object>()
const instantNanoseconds = new WeakMapCtor<object, bigint>()
/**
* Read `[[Nanoseconds]]`. Caller MUST gate on `hasInstantSlot` first; behaviour
* on absent-slot input is undefined.
*/
export function getInstantNanoseconds(o: object): bigint {
return instantNanoseconds.get(o)!
}
/**
* Spec's `RequireInternalSlot(O, [[InitializedTemporalInstant]])` predicate.
* Returns false for non-object inputs.
*/
export function hasInstantSlot(o: unknown): o is object {
return typeof o === 'object' && o !== null && initializedInstant.has(o)
}
/**
* Install `[[InitializedTemporalInstant]]` and `[[Nanoseconds]]` on a receiver.
* Caller is responsible for range-validating `nanoseconds` against
* `IsValidEpochNanoseconds` first; this function does not.
*/
export function setInstantSlots(o: object, nanoseconds: bigint): void {
initializedInstant.add(o)
instantNanoseconds.set(o, nanoseconds)
}