diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 00000000..df310705 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,29 @@ +name: Benchmark +on: + push: + branches: + - master + +jobs: + benchmark: + name: Run Rust benchmark + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - run: rustup toolchain update nightly && rustup default nightly + - name: Run benchmark + run: cargo +nightly bench | tee output.txt + - name: Store benchmark result + uses: rhysd/github-action-benchmark@v1 + with: + name: Rust Benchmark + tool: 'cargo' + output-file-path: output.txt + # Use personal access token instead of GITHUB_TOKEN due to https://github.community/t5/GitHub-Actions/Github-action-not-triggering-gh-pages-upon-push/td-p/26869/highlight/false + github-token: ${{ secrets.RHAI }} + auto-push: true + # Show alert with commit comment on detecting possible performance regression + alert-threshold: '200%' + comment-on-alert: true + fail-on-alert: true + alert-comment-cc-users: '@schungx' diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 03e69ede..01b165a7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,8 +3,8 @@ name: Build on: push: branches: + - main - master - - v1.3-fixes pull_request: {} jobs: diff --git a/CHANGELOG.md b/CHANGELOG.md index 80fc04b2..6987d52e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,13 @@ Bug fixes --------- * Variables introduced inside `try` blocks are now properly cleaned up upon an exception. +* Off-by-one error in character positions after a comment line is now fixed. + +Enhancements +------------ + +* `rhai-repl` tool has a few more commands, such as `strict` to turn on/off _Strict Variables Mode_ and `optimize` to turn on/off script optimization. +* Default features for dependencies (such as `ahash/std` and `num-traits/std`) are no longer required. Version 1.4.1 diff --git a/Cargo.toml b/Cargo.toml index 006c67bf..81d16837 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,7 +26,7 @@ rhai_codegen = { version = "1.2", path = "codegen", default-features = false } serde_bytes = "0.11" [features] -default = ["ahash/std", "num-traits/std"] +default = [] unchecked = [] # unchecked arithmetic sync = [] # restrict to only types that implement Send + Sync no_position = [] # do not track position in the parser diff --git a/no_std/no_std_test/src/main.rs b/no_std/no_std_test/src/main.rs index 3db95447..621029ee 100644 --- a/no_std/no_std_test/src/main.rs +++ b/no_std/no_std_test/src/main.rs @@ -14,7 +14,7 @@ static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT; #[cfg(all(windows, target_env = "msvc"))] #[link(name = "msvcrt")] #[link(name = "libcmt")] -extern {} +extern "C" {} use rhai::{Engine, INT}; @@ -39,11 +39,17 @@ extern "C" fn rust_begin_panic(_: &core::panic::PanicInfo) -> ! { core::intrinsics::abort(); } -#[lang = "eh_personality"] -extern "C" fn eh_personality() {} +#[no_mangle] +extern "C" fn _rust_eh_personality() {} + +#[no_mangle] +extern "C" fn rust_eh_personality() {} #[no_mangle] extern "C" fn rust_eh_register_frames() {} #[no_mangle] extern "C" fn rust_eh_unregister_frames() {} + +#[no_mangle] +extern "C" fn _Unwind_Resume() {} diff --git a/src/ast/expr.rs b/src/ast/expr.rs index b7cb4a52..d2256c5b 100644 --- a/src/ast/expr.rs +++ b/src/ast/expr.rs @@ -21,7 +21,7 @@ use std::{ use std::str::FromStr; #[cfg(not(feature = "no_float"))] -use num_traits::Float; +use num_traits::float::FloatCore as Float; /// _(internals)_ A binary expression. /// Exported under the `internals` feature only. @@ -646,15 +646,14 @@ impl Expr { | Self::Variable(_, pos, _) | Self::Stack(_, pos) | Self::FnCall(_, pos) + | Self::Index(_, _, pos) | Self::Custom(_, pos) | Self::InterpolatedString(_, pos) => *pos, Self::Property(x) => (x.2).1, Self::Stmt(x) => x.position(), - Self::And(x, _) | Self::Or(x, _) | Self::Dot(x, _, _) | Self::Index(x, _, _) => { - x.lhs.position() - } + Self::And(x, _) | Self::Or(x, _) | Self::Dot(x, _, _) => x.lhs.position(), } } /// Override the [position][Position] of the expression. diff --git a/src/bin/rhai-repl.rs b/src/bin/rhai-repl.rs index 1b77f562..2169b642 100644 --- a/src/bin/rhai-repl.rs +++ b/src/bin/rhai-repl.rs @@ -47,6 +47,8 @@ fn print_help() { println!("quit, exit => quit"); println!("scope => print all variables in the scope"); println!("strict => toggle on/off Strict Variables Mode"); + #[cfg(not(feature = "no_optimize"))] + println!("optimize => toggle on/off script optimization"); #[cfg(feature = "metadata")] println!("functions => print all functions defined"); #[cfg(feature = "metadata")] @@ -85,7 +87,9 @@ fn main() { let title = format!("Rhai REPL tool (version {})", env!("CARGO_PKG_VERSION")); println!("{}", title); println!("{0:=<1$}", "", title.len()); - print_help(); + + #[cfg(not(feature = "no_optimize"))] + let mut optimize_level = rhai::OptimizationLevel::Simple; // Initialize scripting engine let mut engine = Engine::new(); @@ -196,6 +200,8 @@ fn main() { let mut ast_u = AST::empty(); let mut ast = AST::empty(); + print_help(); + 'main_loop: loop { print!("rhai-repl> "); stdout().flush().expect("couldn't flush stdout"); @@ -247,6 +253,18 @@ fn main() { println!("Strict Variables Mode turned ON."); continue; } + #[cfg(not(feature = "no_optimize"))] + "optimize" if optimize_level == rhai::OptimizationLevel::Simple => { + optimize_level = rhai::OptimizationLevel::None; + println!("Script optimization turned OFF."); + continue; + } + #[cfg(not(feature = "no_optimize"))] + "optimize" => { + optimize_level = rhai::OptimizationLevel::Simple; + println!("Script optimization turned ON."); + continue; + } "scope" => { print_scope(&scope); continue; @@ -296,7 +314,7 @@ fn main() { #[cfg(not(feature = "no_optimize"))] { - ast = engine.optimize_ast(&scope, r, rhai::OptimizationLevel::Simple); + ast = engine.optimize_ast(&scope, r, optimize_level); } #[cfg(feature = "no_optimize")] diff --git a/src/tokenizer.rs b/src/tokenizer.rs index b23c630e..ba6fb045 100644 --- a/src/tokenizer.rs +++ b/src/tokenizer.rs @@ -1592,11 +1592,11 @@ fn get_next_token_inner( // `\r - start from next line Some('\r') => { eat_next(stream, pos); - pos.new_line(); // `\r\n if let Some('\n') = stream.peek_next() { eat_next(stream, pos); } + pos.new_line(); } // `\n - start from next line Some('\n') => { @@ -1762,11 +1762,11 @@ fn get_next_token_inner( while let Some(c) = stream.get_next() { if c == '\r' { - pos.new_line(); // \r\n if let Some('\n') = stream.peek_next() { eat_next(stream, pos); } + pos.new_line(); break; } if c == '\n' {