Use Arc for environment variables on the stack
This commit is contained in:
parent
0178295363
commit
2758c325cf
|
@ -62,8 +62,8 @@ pub struct ClosureEval {
|
|||
stack: Stack,
|
||||
block: Arc<Block>,
|
||||
arg_index: usize,
|
||||
env_vars: Vec<EnvVars>,
|
||||
env_hidden: HashMap<String, HashSet<String>>,
|
||||
env_vars: Vec<Arc<EnvVars>>,
|
||||
env_hidden: Arc<HashMap<String, HashSet<String>>>,
|
||||
eval: EvalBlockWithEarlyReturnFn,
|
||||
}
|
||||
|
||||
|
|
|
@ -304,7 +304,7 @@ impl EngineState {
|
|||
let mut config_updated = false;
|
||||
|
||||
for mut scope in stack.env_vars.drain(..) {
|
||||
for (overlay_name, mut env) in scope.drain() {
|
||||
for (overlay_name, mut env) in Arc::make_mut(&mut scope).drain() {
|
||||
if let Some(env_vars) = Arc::make_mut(&mut self.env_vars).get_mut(&overlay_name) {
|
||||
// Updating existing overlay
|
||||
for (k, v) in env.drain() {
|
||||
|
|
|
@ -36,9 +36,9 @@ pub struct Stack {
|
|||
/// Variables
|
||||
pub vars: Vec<(VarId, Value)>,
|
||||
/// Environment variables arranged as a stack to be able to recover values from parent scopes
|
||||
pub env_vars: Vec<EnvVars>,
|
||||
pub env_vars: Vec<Arc<EnvVars>>,
|
||||
/// Tells which environment variables from engine state are hidden, per overlay.
|
||||
pub env_hidden: HashMap<String, HashSet<String>>,
|
||||
pub env_hidden: Arc<HashMap<String, HashSet<String>>>,
|
||||
/// List of active overlays
|
||||
pub active_overlays: Vec<String>,
|
||||
pub recursion_count: u64,
|
||||
|
@ -66,7 +66,7 @@ impl Stack {
|
|||
Self {
|
||||
vars: Vec::new(),
|
||||
env_vars: Vec::new(),
|
||||
env_hidden: HashMap::new(),
|
||||
env_hidden: Arc::new(HashMap::new()),
|
||||
active_overlays: vec![DEFAULT_OVERLAY_NAME.to_string()],
|
||||
recursion_count: 0,
|
||||
parent_stack: None,
|
||||
|
@ -119,8 +119,8 @@ impl Stack {
|
|||
|
||||
pub fn with_env(
|
||||
&mut self,
|
||||
env_vars: &[EnvVars],
|
||||
env_hidden: &HashMap<String, HashSet<String>>,
|
||||
env_vars: &[Arc<EnvVars>],
|
||||
env_hidden: &Arc<HashMap<String, HashSet<String>>>,
|
||||
) {
|
||||
// Do not clone the environment if it hasn't changed
|
||||
if self.env_vars.iter().any(|scope| !scope.is_empty()) {
|
||||
|
@ -207,23 +207,24 @@ impl Stack {
|
|||
|
||||
pub fn add_env_var(&mut self, var: String, value: Value) {
|
||||
if let Some(last_overlay) = self.active_overlays.last() {
|
||||
if let Some(env_hidden) = self.env_hidden.get_mut(last_overlay) {
|
||||
if let Some(env_hidden) = Arc::make_mut(&mut self.env_hidden).get_mut(last_overlay) {
|
||||
// if the env var was hidden, let's activate it again
|
||||
env_hidden.remove(&var);
|
||||
}
|
||||
|
||||
if let Some(scope) = self.env_vars.last_mut() {
|
||||
let scope = Arc::make_mut(scope);
|
||||
if let Some(env_vars) = scope.get_mut(last_overlay) {
|
||||
env_vars.insert(var, value);
|
||||
} else {
|
||||
scope.insert(last_overlay.into(), [(var, value)].into_iter().collect());
|
||||
}
|
||||
} else {
|
||||
self.env_vars.push(
|
||||
self.env_vars.push(Arc::new(
|
||||
[(last_overlay.into(), [(var, value)].into_iter().collect())]
|
||||
.into_iter()
|
||||
.collect(),
|
||||
);
|
||||
));
|
||||
}
|
||||
} else {
|
||||
// TODO: Remove panic
|
||||
|
@ -245,9 +246,8 @@ impl Stack {
|
|||
}
|
||||
|
||||
pub fn captures_to_stack_preserve_out_dest(&self, captures: Vec<(VarId, Value)>) -> Stack {
|
||||
// FIXME: this is probably slow
|
||||
let mut env_vars = self.env_vars.clone();
|
||||
env_vars.push(HashMap::new());
|
||||
env_vars.push(Arc::new(HashMap::new()));
|
||||
|
||||
Stack {
|
||||
vars: captures,
|
||||
|
@ -277,7 +277,7 @@ impl Stack {
|
|||
}
|
||||
|
||||
let mut env_vars = self.env_vars.clone();
|
||||
env_vars.push(HashMap::new());
|
||||
env_vars.push(Arc::new(HashMap::new()));
|
||||
|
||||
Stack {
|
||||
vars,
|
||||
|
@ -444,6 +444,7 @@ impl Stack {
|
|||
|
||||
pub fn remove_env_var(&mut self, engine_state: &EngineState, name: &str) -> bool {
|
||||
for scope in self.env_vars.iter_mut().rev() {
|
||||
let scope = Arc::make_mut(scope);
|
||||
for active_overlay in self.active_overlays.iter().rev() {
|
||||
if let Some(env_vars) = scope.get_mut(active_overlay) {
|
||||
if env_vars.remove(name).is_some() {
|
||||
|
@ -456,10 +457,11 @@ impl Stack {
|
|||
for active_overlay in self.active_overlays.iter().rev() {
|
||||
if let Some(env_vars) = engine_state.env_vars.get(active_overlay) {
|
||||
if env_vars.get(name).is_some() {
|
||||
if let Some(env_hidden) = self.env_hidden.get_mut(active_overlay) {
|
||||
env_hidden.insert(name.into());
|
||||
let env_hidden = Arc::make_mut(&mut self.env_hidden);
|
||||
if let Some(env_hidden_in_overlay) = env_hidden.get_mut(active_overlay) {
|
||||
env_hidden_in_overlay.insert(name.into());
|
||||
} else {
|
||||
self.env_hidden
|
||||
env_hidden
|
||||
.insert(active_overlay.into(), [name.into()].into_iter().collect());
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user