@eagleoutice/flowr-dev
Version:
Static Dataflow Analyzer and Program Slicer for the R Programming Language
83 lines (82 loc) • 4.31 kB
TypeScript
import { type FlowrGasConfig, GasLevel, type GasOverrides } from '../../gas';
import type { FlowrAnalyzerGasPlugin } from '../plugins/gas-plugins/flowr-analyzer-gas-plugin';
import type { FlowrAnalyzerContext } from './flowr-analyzer-context';
import type { InvalidationEvent, InvalidationEventReceiver } from '../cache/flowr-cache';
/** Read-only gas context exposed via `ctx.gas`. */
export interface ReadOnlyFlowrAnalyzerGasContext {
readonly name: string;
/**
* Returns the resource-pressure level for `key` (`config.gas.features[key]`).
* Returns `GasLevel.Normal` with zero overhead when the feature factor is 0 or absent
* and no gas plugins are registered (plugins are always consulted and may escalate any key).
*
* Measured from the start of the enclosing contingent, against the thresholds configured for `key`
* (see {@link GasThresholdSpec}), not one allowance shared by everything the analyzer does.
*/
checkGas(key: string): GasLevel;
/**
* A view with a fresh contingent, measured from this call, for one operation to run against.
* The enclosing bounds still apply, `overrides` winning over them. Derives a new object rather than
* mutating this one, so it is safe for nested and concurrent work.
*/
scope(overrides?: GasOverrides): ReadOnlyFlowrAnalyzerGasContext;
}
/**
* The gas context as the owner of the analyzer sees it, reachable via `analyzer.context().gas`.
* Adds the operations that restart a contingent to {@link ReadOnlyFlowrAnalyzerGasContext}.
*/
export interface WriteableFlowrAnalyzerGasContext extends ReadOnlyFlowrAnalyzerGasContext {
/** see {@link FlowrAnalyzerGasContext#reset} */
reset(): void;
/** see {@link FlowrAnalyzerGasContext#withGas} */
withGas<T>(overrides: GasOverrides | undefined, fn: () => T): T;
}
/** Checks heap and elapsed-time pressure for named analysis features. See {@link ReadOnlyFlowrAnalyzerGasContext}. */
export declare class FlowrAnalyzerGasContext implements WriteableFlowrAnalyzerGasContext, InvalidationEventReceiver {
readonly name = "flowr-analyzer-gas-context";
/** what a gas check falls back to when no operation declared a contingent of its own */
private readonly base;
/** the contingents of the operations in flight, innermost last */
private readonly frames;
private readonly config;
private readonly ctx;
private readonly plugins;
constructor(ctx: FlowrAnalyzerContext, config: FlowrGasConfig | undefined, plugins: readonly FlowrAnalyzerGasPlugin[]);
/**
* Restart the contingent, so what follows is measured from now. Supported API: call it between phases
* that should each get the full allowance (`analyzer.context().gas.reset()`).
*
* flowR calls it itself whenever a new analysis begins, so a caller only has to split its *own* phases.
* Operations in flight keep their contingent, as restarting a running traversal's clock would defeat the
* guard bounding it.
*/
reset(): void;
/** A new analysis makes the spent contingent irrelevant. */
receive(_event: InvalidationEvent): void;
/**
* Run `fn` against a fresh contingent bounded by `overrides`, ending when it settles if `fn` is async.
* Every check while `fn` runs sees it, however deep, which is how the bounds reach sites that only ever
* get a context handed to them.
*
* Being ambient, concurrent operations on one analyzer see whichever started last, so prefer
* {@link scope} wherever the context can be threaded through.
*/
withGas<T>(overrides: GasOverrides | undefined, fn: () => T): T;
scope(overrides?: GasOverrides): ReadOnlyFlowrAnalyzerGasContext;
private derive;
private viewOf;
private drop;
private activeScope;
/**
* The innermost layer stating this bound wins, the configured thresholds apply when none does.
* Resolved per bound, so a layer naming only `critical` leaves `problematic` to the layer outside it.
*/
private bound;
/** An override naming the feature enables it even when the config disables it. */
private factorFor;
private memoryLevel;
private static maxLevel;
private timeLevel;
checkGas(key: string): GasLevel;
private levelFor;
}