UNPKG

@eagleoutice/flowr

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

82 lines 3.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FlowrAnalyzerControlFlowCache = void 0; const objectmap_1 = require("../../util/collections/objectmap"); const cfg_simplification_1 = require("../../control-flow/cfg-simplification"); const cfg_kind_1 = require("../cfg-kind"); const assert_1 = require("../../util/assert"); const extract_cfg_1 = require("../../control-flow/extract-cfg"); class FlowrAnalyzerControlFlowCache { cache = new objectmap_1.ObjectMap(); peek(kind, simplifications) { return this.cache.get([simplifications ?? [], kind]); } async get(force, kind, cfgCacheInfo, simplifications) { (0, assert_1.guard)(kind === cfg_kind_1.CfgKind.Quick ? simplifications === undefined : true, 'Cannot apply simplifications to quick CFG'); simplifications ??= []; const orderedSimplifications = this.normalizeSimplificationOrder(simplifications); const cached = force ? { cfg: undefined, missingSimplifications: orderedSimplifications } : this.tryGetCachedCfg(orderedSimplifications, kind); let cfg = cached.cfg; if (!cfg) { cfg = await this.createAndCacheBaseCfg(kind, cfgCacheInfo); } if (cached.missingSimplifications.length > 0) { const cfgPassInfo = { dfg: (await cfgCacheInfo.dfg()).graph, ctx: cfgCacheInfo.ctx, ast: await cfgCacheInfo.ast() }; cfg = (0, cfg_simplification_1.simplifyControlFlowInformation)(cfg, cfgPassInfo, cached.missingSimplifications); } this.cache.set([orderedSimplifications, kind], cfg); return cfg; } /** * Create and cache the base CFG without simplifications. */ async createAndCacheBaseCfg(kind, { cfgQuick, dfg, ctx, ast }) { let result; switch (kind) { case cfg_kind_1.CfgKind.WithDataflow: result = (0, extract_cfg_1.extractCfg)(await ast(), ctx, (await dfg()).graph); break; case cfg_kind_1.CfgKind.NoDataflow: result = (0, extract_cfg_1.extractCfg)(await ast(), ctx); break; case cfg_kind_1.CfgKind.NoFunctionDefs: result = (0, extract_cfg_1.extractCfg)(await ast(), ctx, undefined, undefined, true); break; case cfg_kind_1.CfgKind.Quick: result = cfgQuick ?? (0, extract_cfg_1.extractCfgQuick)(await ast()); break; } this.cache.set([[], kind], result); return result; } /** * Try to get a cached CFG with some of the requested simplifications already applied. * Matches the longest prefix of simplifications available. * @returns The cached CFG and the missing simplifications to be applied, or `undefined` if no cached CFG is available. */ tryGetCachedCfg(simplifications, kind) { for (let prefixLen = simplifications.length; prefixLen >= 0; prefixLen--) { const prefix = simplifications.slice(0, prefixLen); const cached = this.cache.get([prefix, kind]); if (cached !== undefined) { return { cfg: cached, missingSimplifications: simplifications.slice(prefixLen) }; } } return { cfg: undefined, missingSimplifications: simplifications }; } /** * Normalize the order of simplification passes. * Is currently an identity function, but may be extended in the future to enforce a specific order using heuristics. * @param simplifications - the requested simplification passes. */ normalizeSimplificationOrder(simplifications) { return simplifications; } } exports.FlowrAnalyzerControlFlowCache = FlowrAnalyzerControlFlowCache; //# sourceMappingURL=flowr-analyzer-controlflow-cache.js.map