git.delta.rocks / jrsonnet / refs/commits / 90cacba70c63

difftreelog

perf(evaluator) emove expr from stacktraces

Лач2020-06-25parent: #f5b0724.patch.diff
in: master

4 files changed

modifiedcmds/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;
modifiedcrates/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>);
 
modifiedcrates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
35 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.value
255 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,
371371
372pub 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 ({:?}): {}",
modifiedcrates/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();