difftreelog
perf(evaluator) emove expr from stacktraces
in: master
4 files changed
cmds/jrsonnet/src/main.rsdiffbeforeafterboth--- a/cmds/jrsonnet/src/main.rs
+++ b/cmds/jrsonnet/src/main.rs
@@ -271,10 +271,7 @@
};
for item in trace.0.iter() {
let desc = &item.1;
- if (item.0).1.is_none() {
- continue;
- }
- let source = (item.0).1.clone().unwrap();
+ let source = item.0.clone();
let code = evaluator.get_source(&source.0);
if code.is_none() {
continue;
crates/jsonnet-evaluator/src/error.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/error.rs
+++ b/crates/jsonnet-evaluator/src/error.rs
@@ -1,6 +1,6 @@
use crate::ValType;
-use jsonnet_parser::LocExpr;
-use std::path::PathBuf;
+use jsonnet_parser::ExprLocation;
+use std::{path::PathBuf, rc::Rc};
#[derive(Debug, Clone)]
pub enum Error {
@@ -38,7 +38,7 @@
}
#[derive(Clone, Debug)]
-pub struct StackTraceElement(pub LocExpr, pub String);
+pub struct StackTraceElement(pub Rc<ExprLocation>, pub String);
#[derive(Debug, Clone)]
pub struct StackTrace(pub Vec<StackTraceElement>);
crates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth35 b.name.clone(),35 b.name.clone(),36 LazyBinding::Bindable(Rc::new(move |this, super_obj| {36 LazyBinding::Bindable(Rc::new(move |this, super_obj| {37 Ok(lazy_val!(closure!(clone context_creator, clone b, ||37 Ok(lazy_val!(closure!(clone context_creator, clone b, ||38 push(b.value.clone(), "thunk".to_owned(), ||{38 push(&b.value.1, "thunk", ||{39 evaluate(39 evaluate(40 context_creator.0(this.clone(), super_obj.clone())?,40 context_creator.0(this.clone(), super_obj.clone())?,41 &b.value41 &b.value255 visibility: visibility.clone(),255 visibility: visibility.clone(),256 invoke: LazyBinding::Bindable(Rc::new(256 invoke: LazyBinding::Bindable(Rc::new(257 closure!(clone name, clone value, clone context_creator, |this, super_obj| {257 closure!(clone name, clone value, clone context_creator, |this, super_obj| {258 Ok(LazyVal::new_resolved(push(value.clone(), "object ".to_owned()+&name+" field", ||{258 Ok(LazyVal::new_resolved(push(&value.1, "object field", ||{259 let context = context_creator.0(this, super_obj)?;259 let context = context_creator.0(this, super_obj)?;260 evaluate(260 evaluate(261 context,261 context,371371372pub fn evaluate(context: Context, expr: &LocExpr) -> Result<Val> {372pub fn evaluate(context: Context, expr: &LocExpr) -> Result<Val> {373 use Expr::*;373 use Expr::*;374 let locexpr = expr.clone();375 let LocExpr(expr, loc) = expr;374 let LocExpr(expr, loc) = expr;376 Ok(match &**expr {375 Ok(match &**expr {377 Literal(LiteralType::This) => Val::Obj(376 Literal(LiteralType::This) => Val::Obj(394 Num(v) => Val::Num(*v),393 Num(v) => Val::Num(*v),395 BinaryOp(v1, o, v2) => evaluate_binary_op_special(context, &v1, *o, &v2)?,394 BinaryOp(v1, o, v2) => evaluate_binary_op_special(context, &v1, *o, &v2)?,396 UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(context, v)?)?,395 UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(context, v)?)?,397 Var(name) => push(locexpr, "var".to_owned(), || {396 Var(name) => push(loc, "var", || {398 Val::Lazy(context.binding(&name)?).unwrap_if_lazy()397 Val::Lazy(context.binding(&name)?).unwrap_if_lazy()399 })?,398 })?,400 Index(LocExpr(v, _), index) if matches!(&**v, Expr::Literal(LiteralType::Super)) => {399 Index(LocExpr(v, _), index) if matches!(&**v, Expr::Literal(LiteralType::Super)) => {733 if *tailstrict {732 if *tailstrict {734 body()?733 body()?735 } else {734 } else {736 push(locexpr, "function call".to_owned(), body)?735 push(loc, "function call", body)?737 }736 }738 }737 }739 _ => panic!("{:?} is not a function", value),738 _ => panic!("{:?} is not a function", value),740 }739 }741 }740 }742 Function(params, body) => evaluate_method(context, params.clone(), body.clone()),741 Function(params, body) => evaluate_method(context, params.clone(), body.clone()),743 AssertExpr(AssertStmt(value, msg), returned) => {742 AssertExpr(AssertStmt(value, msg), returned) => {744 let assertion_result = push(value.clone(), "assertion condition".to_owned(), || {743 let assertion_result = push(&value.1, "assertion condition", || {745 evaluate(context.clone(), &value)?744 evaluate(context.clone(), &value)?746 .try_cast_bool("assertion condition should be boolean")745 .try_cast_bool("assertion condition should be boolean")747 })?;746 })?;748 if assertion_result {747 if assertion_result {749 push(750 returned.clone(),751 "assert 'return' branch".to_owned(),752 || evaluate(context, returned),748 evaluate(context, returned)?753 )?754 } else if let Some(msg) = msg {749 } else if let Some(msg) = msg {755 panic!(750 panic!(756 "assertion failed ({:?}): {}",751 "assertion failed ({:?}): {}",crates/jsonnet-evaluator/src/lib.rsdiffbeforeafterboth--- a/crates/jsonnet-evaluator/src/lib.rs
+++ b/crates/jsonnet-evaluator/src/lib.rs
@@ -81,15 +81,21 @@
pub(crate) static EVAL_STATE: RefCell<Option<EvaluationState>> = RefCell::new(None)
}
pub(crate) fn with_state<T>(f: impl FnOnce(&EvaluationState) -> T) -> T {
- EVAL_STATE.with(
- |s| f(s.borrow().as_ref().unwrap()),
- )
+ EVAL_STATE.with(|s| f(s.borrow().as_ref().unwrap()))
}
pub(crate) fn create_error<T>(err: Error) -> Result<T> {
with_state(|s| s.error(err))
}
-pub(crate) fn push<T>(e: LocExpr, comment: String, f: impl FnOnce() -> Result<T>) -> Result<T> {
- with_state(|s| s.push(e, comment, f))
+pub(crate) fn push<T>(
+ e: &Option<Rc<ExprLocation>>,
+ comment: &str,
+ f: impl FnOnce() -> Result<T>,
+) -> Result<T> {
+ if e.is_some() {
+ with_state(|s| s.push(e.clone().unwrap(), comment.to_owned(), f))
+ } else {
+ f()
+ }
}
/// Maintains stack trace and import resolution
@@ -247,7 +253,12 @@
Context::new().extend_unbound(new_bindings, None, None, None)
}
- pub fn push<T>(&self, e: LocExpr, comment: String, f: impl FnOnce() -> Result<T>) -> Result<T> {
+ pub fn push<T>(
+ &self,
+ e: Rc<ExprLocation>,
+ comment: String,
+ f: impl FnOnce() -> Result<T>,
+ ) -> Result<T> {
{
let mut stack = self.0.stack.borrow_mut();
if stack.len() > self.0.settings.max_stack_frames {
@@ -302,26 +313,18 @@
use super::Val;
use crate::EvaluationState;
use jsonnet_parser::*;
- use std::path::PathBuf;
+ use std::{path::PathBuf, rc::Rc};
#[test]
fn eval_state_stacktrace() {
let state = EvaluationState::default();
state
.push(
- loc_expr!(
- Expr::Num(0.0),
- true,
- (PathBuf::from("test1.jsonnet"), 10, 20)
- ),
+ Rc::new(ExprLocation(PathBuf::from("test1.jsonnet"), 10, 20)),
"outer".to_owned(),
|| {
state.push(
- loc_expr!(
- Expr::Num(0.0),
- true,
- (PathBuf::from("test2.jsonnet"), 30, 40)
- ),
+ Rc::new(ExprLocation(PathBuf::from("test2.jsonnet"), 30, 40)),
"inner".to_owned(),
|| {
state.print_stack_trace();