UNPKG

@eagleoutice/flowr-dev

Version:

Static Dataflow Analyzer and Program Slicer for the R Programming Language

75 lines 2.96 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.envFingerprint = envFingerprint; exports.fingerprint = fingerprint; const object_hash_1 = __importDefault(require("object-hash")); const environment_1 = require("../../dataflow/environments/environment"); const HashOptions = { algorithm: 'md5', excludeKeys: (key) => key === 'id' || key === 'value', respectFunctionProperties: false, respectFunctionNames: false, ignoreUnknown: true, replacer: (v) => (0, environment_1.isDefaultBuiltInEnvironment)(v) ? undefined : v }; /* definitions, definition maps and frames are shared across the environments a slice builds, and a definition may * hold a whole environment of its own (`envState`), so each is hashed once instead of on every fingerprint. The * map is keyed separately from the frame because cloning a frame shares its definitions until one side writes * (see {@link Environment#clone}): the graph holds many frames per distinct set of definitions, and hashing that * set is what costs. */ const definitionHashes = new WeakMap(); const memoryHashes = new WeakMap(); const frameHashes = new WeakMap(); function definitionHash(definition) { let hash = definitionHashes.get(definition); if (hash === undefined) { hash = (0, object_hash_1.default)(definition, HashOptions); definitionHashes.set(definition, hash); } return hash; } function memoryHash(memory) { let hash = memoryHashes.get(memory); if (hash === undefined) { const entries = []; for (const [name, definitions] of memory) { entries.push(`${String(name)}=${definitions.map(definitionHash).join(',')}`); } entries.sort(); hash = (0, object_hash_1.default)(entries, HashOptions); memoryHashes.set(memory, hash); } return hash; } function frameHash(frame) { let hash = frameHashes.get(frame); if (hash === undefined) { hash = (0, object_hash_1.default)([frame.n, frame.t, frame.closure, frame.globalEnv === true, memoryHash(frame.memory)], HashOptions); frameHashes.set(frame, hash); } return hash; } /** * Calculate a fingerprint for the given R environment information * @see {@link fingerprint} */ function envFingerprint(env) { const parts = [String(env.level)]; let frame = env.current; while (frame !== undefined && !frame.builtInEnv) { parts.push(frameHash(frame)); frame = frame.parent; } return parts.join('|'); } /** * Calculate a fingerprint for the given node id and environment fingerprint * @see {@link envFingerprint} */ function fingerprint(id, envFingerprint, onlyForSideEffects) { return `${id}-${envFingerprint}-${onlyForSideEffects ? '0' : '1'}`; } //# sourceMappingURL=fingerprint.js.map