Skip to main content

sim_kernel/library/registry/
overlay.rs

1use std::collections::{BTreeMap, BTreeSet};
2
3use crate::{
4    ClassId, CodecId, FunctionId, LibId, MacroId, NumberDomainId, Result, RuntimeId, ShapeId,
5    SiteId, Symbol, Value,
6    library::{ExportKind, LoadedLib, RegisteredTest},
7    number_domain::{
8        NumberBinaryOp, NumberReductionOp, NumberUnaryOp, ValueNumberBinaryOp,
9        ValueNumberReductionOp, ValueNumberUnaryOp, ValuePromotionRule,
10    },
11};
12
13use super::{LoadDelta, Registry};
14
15impl Registry {
16    /// Runs `f` against the registry under a catalog overlay, committing on
17    /// success and rolling both the catalog and the projection caches back to
18    /// their captured state on error.
19    pub fn with_catalog_overlay<F, R>(&mut self, f: F) -> Result<R>
20    where
21        F: FnOnce(&mut Self) -> Result<R>,
22    {
23        let state = RegistryOverlayState::capture(self);
24        self.catalog.begin_overlay()?;
25        match f(self) {
26            Ok(value) => match self.catalog.commit_overlay() {
27                Ok(()) => Ok(value),
28                Err(err) => {
29                    state.restore(self);
30                    Err(err)
31                }
32            },
33            Err(err) => {
34                self.catalog.rollback_overlay();
35                state.restore(self);
36                Err(err)
37            }
38        }
39    }
40}
41
42#[derive(Clone)]
43struct RegistryOverlayState {
44    libs: Vec<LoadedLib>,
45    libs_by_symbol: BTreeMap<Symbol, LibId>,
46    load_deltas: BTreeMap<LibId, LoadDelta>,
47    load_dependencies: BTreeMap<LibId, BTreeSet<LibId>>,
48    export_symbols: BTreeMap<ExportKind, BTreeMap<Symbol, RuntimeId>>,
49    class_symbol_cache: BTreeMap<Symbol, ClassId>,
50    function_symbol_cache: BTreeMap<Symbol, FunctionId>,
51    macro_symbol_cache: BTreeMap<Symbol, MacroId>,
52    shape_symbol_cache: BTreeMap<Symbol, ShapeId>,
53    codec_symbol_cache: BTreeMap<Symbol, CodecId>,
54    number_domain_symbol_cache: BTreeMap<Symbol, NumberDomainId>,
55    site_symbol_cache: BTreeMap<Symbol, SiteId>,
56    plain_value_cache: BTreeMap<Symbol, Value>,
57    class_value_cache: BTreeMap<ClassId, Value>,
58    function_value_cache: BTreeMap<FunctionId, Value>,
59    macro_value_cache: BTreeMap<MacroId, Value>,
60    shape_value_cache: BTreeMap<ShapeId, Value>,
61    codec_value_cache: BTreeMap<CodecId, Value>,
62    number_domain_value_cache: BTreeMap<NumberDomainId, Value>,
63    site_value_cache: BTreeMap<SiteId, Value>,
64    number_domain_order: Option<Vec<NumberDomainId>>,
65    tests: BTreeMap<Symbol, RegisteredTest>,
66    tests_by_lib: BTreeMap<Symbol, Vec<Symbol>>,
67    promotion_rules: Vec<crate::number_domain::PromotionRule>,
68    value_promotion_rules: Vec<ValuePromotionRule>,
69    number_unary_ops: Vec<NumberUnaryOp>,
70    number_reduction_ops: Vec<NumberReductionOp>,
71    number_binary_ops: Vec<NumberBinaryOp>,
72    value_number_unary_ops: Vec<ValueNumberUnaryOp>,
73    value_number_reduction_ops: Vec<ValueNumberReductionOp>,
74    value_number_binary_ops: Vec<ValueNumberBinaryOp>,
75}
76
77impl RegistryOverlayState {
78    fn capture(registry: &Registry) -> Self {
79        Self {
80            libs: registry.libs.clone(),
81            libs_by_symbol: registry.libs_by_symbol.clone(),
82            load_deltas: registry.load_deltas.clone(),
83            load_dependencies: registry.load_dependencies.clone(),
84            export_symbols: registry.export_symbols.clone(),
85            class_symbol_cache: registry.class_symbol_cache.clone(),
86            function_symbol_cache: registry.function_symbol_cache.clone(),
87            macro_symbol_cache: registry.macro_symbol_cache.clone(),
88            shape_symbol_cache: registry.shape_symbol_cache.clone(),
89            codec_symbol_cache: registry.codec_symbol_cache.clone(),
90            number_domain_symbol_cache: registry.number_domain_symbol_cache.clone(),
91            site_symbol_cache: registry.site_symbol_cache.clone(),
92            plain_value_cache: registry.plain_value_cache.clone(),
93            class_value_cache: registry.class_value_cache.clone(),
94            function_value_cache: registry.function_value_cache.clone(),
95            macro_value_cache: registry.macro_value_cache.clone(),
96            shape_value_cache: registry.shape_value_cache.clone(),
97            codec_value_cache: registry.codec_value_cache.clone(),
98            number_domain_value_cache: registry.number_domain_value_cache.clone(),
99            site_value_cache: registry.site_value_cache.clone(),
100            number_domain_order: registry.number_domain_order.clone(),
101            tests: registry.tests.clone(),
102            tests_by_lib: registry.tests_by_lib.clone(),
103            promotion_rules: registry.promotion_rules.clone(),
104            value_promotion_rules: registry.value_promotion_rules.clone(),
105            number_unary_ops: registry.number_unary_ops.clone(),
106            number_reduction_ops: registry.number_reduction_ops.clone(),
107            number_binary_ops: registry.number_binary_ops.clone(),
108            value_number_unary_ops: registry.value_number_unary_ops.clone(),
109            value_number_reduction_ops: registry.value_number_reduction_ops.clone(),
110            value_number_binary_ops: registry.value_number_binary_ops.clone(),
111        }
112    }
113
114    fn restore(self, registry: &mut Registry) {
115        registry.libs = self.libs;
116        registry.libs_by_symbol = self.libs_by_symbol;
117        registry.load_deltas = self.load_deltas;
118        registry.load_dependencies = self.load_dependencies;
119        registry.export_symbols = self.export_symbols;
120        registry.class_symbol_cache = self.class_symbol_cache;
121        registry.function_symbol_cache = self.function_symbol_cache;
122        registry.macro_symbol_cache = self.macro_symbol_cache;
123        registry.shape_symbol_cache = self.shape_symbol_cache;
124        registry.codec_symbol_cache = self.codec_symbol_cache;
125        registry.number_domain_symbol_cache = self.number_domain_symbol_cache;
126        registry.site_symbol_cache = self.site_symbol_cache;
127        registry.plain_value_cache = self.plain_value_cache;
128        registry.class_value_cache = self.class_value_cache;
129        registry.function_value_cache = self.function_value_cache;
130        registry.macro_value_cache = self.macro_value_cache;
131        registry.shape_value_cache = self.shape_value_cache;
132        registry.codec_value_cache = self.codec_value_cache;
133        registry.number_domain_value_cache = self.number_domain_value_cache;
134        registry.site_value_cache = self.site_value_cache;
135        registry.number_domain_order = self.number_domain_order;
136        registry.tests = self.tests;
137        registry.tests_by_lib = self.tests_by_lib;
138        registry.promotion_rules = self.promotion_rules;
139        registry.value_promotion_rules = self.value_promotion_rules;
140        registry.number_unary_ops = self.number_unary_ops;
141        registry.number_reduction_ops = self.number_reduction_ops;
142        registry.number_binary_ops = self.number_binary_ops;
143        registry.value_number_unary_ops = self.value_number_unary_ops;
144        registry.value_number_reduction_ops = self.value_number_reduction_ops;
145        registry.value_number_binary_ops = self.value_number_binary_ops;
146    }
147}