mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-31 07:23:06 +08:00
Encoding an array key added each element's size to a running length with unchecked arithmetic, and wrote into a fixed stack buffer whenever the sum fit. A sparse array with a large length (2^29 elements or more) wrapped the sum on 32-bit targets, so the write landed before the buffer; on every target the encoder also visited every index of such an array. Array keys now have at most 65536 elements, and their encoding at most 2^31 - 1 bytes. The size is computed first with sums that cannot wrap, the buffer is sized to it, and keys over either limit make the lookup or insert throw a TypeError before anything is read or written. The Node.js implementation throws the same TypeError for keys of more than 65536 elements. Sparse elements are walked in one pass in index order, and the index growth computation checks its size arithmetic too.
55 lines
2.8 KiB
TypeScript
55 lines
2.8 KiB
TypeScript
/** An allocation context for ProgramLifetime instances (@scriptc/types).
|
|
* In scriptc builds, instances created while `run` executes belong to the
|
|
* region and are freed together once the region is released and nothing
|
|
* outside it refers to them. Under Node.js, `run` calls its callback and
|
|
* `release` does nothing. */
|
|
export declare class LifetimeRegion {
|
|
constructor();
|
|
/** Calls `fn` with this region as the current region and returns its
|
|
* result. ProgramLifetime instances created during the call, outside
|
|
* nested `run` calls of other regions, belong to this region. Work that
|
|
* resumes after an `await` inside `fn` runs outside the region. */
|
|
run<T>(fn: () => T): T;
|
|
/** Requests that the region be freed. Its instances are freed once
|
|
* nothing outside the region refers to any of them; until then the
|
|
* region stays allocated. Later `run` calls allocate outside the region.
|
|
* Never observable except through memory use. */
|
|
release(): void;
|
|
}
|
|
|
|
/** A named, append-only table of published values (@scriptc/threads).
|
|
* Every construction with one name opens the same table: in scriptc builds
|
|
* all threads of the process share it, and under Node.js each thread has
|
|
* its own. A key's value never changes once stored, and storing a value
|
|
* publishes it, so stored values and everything they reach are immutable.
|
|
* scriptc requires the name to be a string literal and every construction
|
|
* of one name to use the same type arguments. */
|
|
export declare class InternTable<
|
|
K extends string | number | readonly number[] | readonly string[],
|
|
V,
|
|
> {
|
|
/** Opens the table called `name`. */
|
|
constructor(name: string);
|
|
/** The number of entries. */
|
|
readonly size: number;
|
|
/** The value stored under `key`, or undefined. String and number keys
|
|
* compare like Map keys: strings by content, numbers by SameValueZero.
|
|
* Array keys compare by their elements in the same way; a hole and an
|
|
* undefined element are equal. Every method throws a TypeError for an
|
|
* array key of more than 65536 elements. */
|
|
get(key: K): V | undefined;
|
|
/** Whether `key` has a value. */
|
|
has(key: K): boolean;
|
|
/** Returns the value stored under `key`. When there is none, publishes
|
|
* `value`, stores it and returns it. Throws publish's TypeError, storing
|
|
* nothing, when `value` cannot be published. */
|
|
getOrInsert(key: K, value: V): V;
|
|
/** Returns the value stored under `key`. When there is none, calls
|
|
* `callback(key)`, publishes its result and stores it, unless a value was
|
|
* stored under `key` meanwhile (by the callback, or in scriptc builds by
|
|
* another thread). Returns the stored value. No lock is held while the
|
|
* callback runs: threads that miss one key at the same time may each
|
|
* call it. */
|
|
getOrInsertComputed(key: K, callback: (key: K) => V): V;
|
|
}
|