sim_kernel/library/registry/
overlay.rs1use 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 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}