Skip to content

Latest commit

 

History

History
33 lines (24 loc) · 5.8 KB

File metadata and controls

33 lines (24 loc) · 5.8 KB

Runtime semantics

The runtime exists where C++ standard-library behavior is observably different from TypeScript. Wrappers are justified by semantics, not by a desire to reproduce JavaScript method names.

Initial invariants

  • Array<T> and Map<K, V> are reference values. Copying a wrapper preserves backing identity; clone() explicitly creates new storage.
  • Array<T>::at and Map<K, V>::get return absence rather than throwing for a missing index or key.
  • Array inclusion and map key identity use SameValueZero: NaN equals NaN and positive and negative zero are the same value.
  • Map iteration retains insertion order. Updating an existing key does not move it.
  • Undefined, Null, and Presence<T> keep the two TypeScript sentinels distinct from one another and from an ordinary value.
  • String stores UTF-16 code units, so length, indexing, slicing, splitting, and unpaired-surrogate behavior do not depend on the machine encoding. UTF-8 conversion is an explicit boundary.
  • Set<T> shares Map's SameValueZero and insertion-order rules. Typed-array copies and subarray share a fixed backing store, while slice copies; clamped bytes use saturating ties-to-even conversion. ArrayBufferLike retains ordinary, shared, or host-owned memory together with stable backing identity, lifetime, mutability, and concurrency policy. Typed arrays and DataView keep that backing without copying.
  • Blob copies its input parts into immutable shared byte storage. String parts use UTF-8, MIME types are printable ASCII normalized to lowercase, byte slices use JavaScript's signed-index rules, and text decoding follows the runtime's UTF-8 replacement behavior.
  • URI component encoding operates on UTF-16 scalar values and emits uppercase UTF-8 percent escapes; decoding rejects malformed escapes and UTF-8. Base64 uses the browser binary-string domain, strips the specified ASCII whitespace while decoding, and rejects input code units outside one byte while encoding.
  • Stream copies share identity and one lock state. Native sinks and sources return Task values for writes, close, abort, reads, and cancellation; released readers and writers reject further operations. The current contract does not yet model Web Streams backpressure, piping, transforms, or teeing.
  • Shared container and binary-view handles use logical constness: a compiler-emitted value capture cannot rebind its handle, but it can mutate the JavaScript object referenced by that handle. TextEncoder converts UTF-16 scalar values to UTF-8 and replaces each unpaired surrogate with U+FFFD.
  • WeakSet<K> and WeakMap<K, V> copy as aliases, compare keys by object identity, remove expired entries opportunistically, and never retain or enumerate keys. Flight references and Array<T> provide recoverable weak ownership; host handles require an explicit policy with the same lifetime and identity guarantees.
  • Task<T> is copyable and shares one settlement. Observers run through a non-reentrant executor, completed tasks can be awaited repeatedly, and exception or non-exception rejection values retain their identity and type.
  • Date applies ECMAScript-style finite millisecond clipping and stores an epoch instant. The initial calendar projection is UTC-only and is limited to the range represented by C++20 std::chrono::year; local-zone getFullYear behavior is not yet claimed.
  • round follows Math.round: nearest-integer ties move toward positive infinity, inputs from -0.5 through negative zero retain a negative-zero result, and NaN and infinities pass through unchanged.

Deliberate gaps

The task runtime implements flight-runtime-task-capability-abi/1: synchronous executor invocation, first-call-wins settlement, task assimilation, queued then and rejection recovery, awaited finally cleanup, ordered all/join_all, ordered non-rejecting all_settled, coroutine suspension and resumption, exact rejection, and void. TaskSettlement<T> preserves status plus the exact fulfilled value or rejection reason, and all_settled_tasks bridges semantic arrays to that carrier. QueueExecutor provides the deterministic default and ExecutorScope installs a host executor while tasks are created or resumed. An executor must enqueue rather than invoke post reentrantly; host integrations own the event-loop wakeup and thread-affinity policy. Cancellation and structured concurrency remain separate future capabilities rather than being implied by Promise compatibility.

Array<T> currently requires copyable elements for operations that return copied values. Map<K, V> uses an ordered linear store to make identity and order correct before optimization; a later index must preserve those results exactly. Object keys will need an explicit reference-identity trait rather than accidental value equality.

String case conversion is exact for ASCII and delegates non-ASCII input to the active UnicodeService. The core never consults the process locale. Production hosts must provide a Unicode implementation with a pinned Unicode-data version and conformance tests for expansion, supplementary characters, Turkish casing, normalization non-equivalence, and unpaired surrogates.

External ArrayBufferLike storage must remain valid through its shared owner and suitably aligned for each typed view. Read-only backing supports DataView reads and rejects writes; mutable typed arrays reject read-only backing at construction. Shared-memory policy is observable metadata, while callers remain responsible for synchronization. Atomic operations, detachment, resizable buffers, and JavaScript's full shared-memory access model remain outside the current runtime contract.

Capability status in flight/contract.hpp is machine-readable but intentionally coarse during incubation. initial means an implementation and local semantic tests exist; it does not mean the backend as a whole is production-ready.