From 8d34ffb9f571e43bd220b93eb3738a7cc0188319 Mon Sep 17 00:00:00 2001 From: Stephen Chung Date: Mon, 24 Jan 2022 08:34:21 +0800 Subject: [PATCH] Fix bug in try block. --- CHANGELOG.md | 7 +++++- src/eval/stmt.rs | 10 +++++--- tests/get_set.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++ tests/throw.rs | 5 ++++ 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 19e31808..80fc04b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,14 @@ Rhai Release Notes ================== -Version 1.5.0 +Version 1.4.2 ============= +Bug fixes +--------- + +* Variables introduced inside `try` blocks are now properly cleaned up upon an exception. + Version 1.4.1 ============= diff --git a/src/eval/stmt.rs b/src/eval/stmt.rs index 47760a04..96aa85bc 100644 --- a/src/eval/stmt.rs +++ b/src/eval/stmt.rs @@ -35,7 +35,7 @@ impl Engine { state.scope_level += 1; } - let mut result = Dynamic::UNIT; + let mut result = Ok(Dynamic::UNIT); for stmt in statements { let _mods_len = global.num_imports(); @@ -49,7 +49,11 @@ impl Engine { stmt, restore_orig_state, level, - )?; + ); + + if result.is_err() { + break; + } #[cfg(not(feature = "no_module"))] if matches!(stmt, Stmt::Import(_, _, _)) { @@ -89,7 +93,7 @@ impl Engine { state.always_search_scope = orig_always_search_scope; } - Ok(result) + result } /// Evaluate an op-assignment statement. diff --git a/tests/get_set.rs b/tests/get_set.rs index ee8e55f5..7ec97451 100644 --- a/tests/get_set.rs +++ b/tests/get_set.rs @@ -302,3 +302,68 @@ fn test_get_set_collection() -> Result<(), Box> { Ok(()) } + +#[cfg(not(feature = "no_index"))] +#[test] +fn test_get_set_indexer() -> Result<(), Box> { + type MyMap = std::collections::BTreeMap; + + let mut engine = Engine::new(); + + engine + .register_type_with_name::("MyMap") + .register_fn("new_map", || MyMap::new()) + .register_indexer_get_result(|map: &mut MyMap, index: &str| { + map.get(index) + .cloned() + .ok_or_else(|| format!("Index `{}` not found!", index).into()) + }) + .register_indexer_set(|map: &mut MyMap, index: &str, value: INT| { + map.insert(index.to_string(), value); + }) + .register_fn("to_string", |map: &mut MyMap| format!("{:?}", map)); + + assert_eq!( + engine.eval::( + r#" + let my_map = new_map(); + my_map["eggs"] = 42; + my_map["eggs"] + "#, + )?, + 42 + ); + + assert!(engine + .eval::( + r#" + let my_map = new_map(); + my_map["eggs"] = 42; + my_map["not_found"] + "#, + ) + .is_err()); + + assert_eq!( + engine.eval::( + r#" + let my_map = new_map(); + my_map["eggs"] = 42; + + try { + let eggs = my_map["eggs"]; + let eggs = my_map["not found"]; + } + catch(x) + { + print("Not found!"); + } + + my_map["eggs"] + "#, + )?, + 42 + ); + + Ok(()) +} diff --git a/tests/throw.rs b/tests/throw.rs index e0617559..9aaccab0 100644 --- a/tests/throw.rs +++ b/tests/throw.rs @@ -29,6 +29,11 @@ fn test_try_catch() -> Result<(), Box> { 123 ); + assert_eq!( + engine.eval::("let x = 42; try { let y = 123; print(x/0); } catch { x = 0 } x")?, + 0 + ); + #[cfg(not(feature = "no_function"))] assert_eq!( engine.eval::(