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
1use crate::ValType;1use crate::ValType;
2use jsonnet_parser::LocExpr;2use jsonnet_parser::ExprLocation;
3use std::path::PathBuf;3use std::{path::PathBuf, rc::Rc};
44
5#[derive(Debug, Clone)]5#[derive(Debug, Clone)]
6pub enum Error {6pub enum Error {
38}38}
3939
40#[derive(Clone, Debug)]40#[derive(Clone, Debug)]
41pub struct StackTraceElement(pub LocExpr, pub String);41pub struct StackTraceElement(pub Rc<ExprLocation>, pub String);
42#[derive(Debug, Clone)]42#[derive(Debug, Clone)]
43pub struct StackTrace(pub Vec<StackTraceElement>);43pub struct StackTrace(pub Vec<StackTraceElement>);
4444
modifiedcrates/jsonnet-evaluator/src/evaluate.rsdiffbeforeafterboth
--- a/crates/jsonnet-evaluator/src/evaluate.rs
+++ b/crates/jsonnet-evaluator/src/evaluate.rs
@@ -35,7 +35,7 @@
 			b.name.clone(),
 			LazyBinding::Bindable(Rc::new(move |this, super_obj| {
 				Ok(lazy_val!(closure!(clone context_creator, clone b, ||
-					push(b.value.clone(), "thunk".to_owned(), ||{
+					push(&b.value.1, "thunk", ||{
 						evaluate(
 							context_creator.0(this.clone(), super_obj.clone())?,
 							&b.value
@@ -255,7 +255,7 @@
 								visibility: visibility.clone(),
 								invoke: LazyBinding::Bindable(Rc::new(
 									closure!(clone name, clone value, clone context_creator, |this, super_obj| {
-										Ok(LazyVal::new_resolved(push(value.clone(), "object ".to_owned()+&name+" field", ||{
+										Ok(LazyVal::new_resolved(push(&value.1, "object field", ||{
 											let context = context_creator.0(this, super_obj)?;
 											evaluate(
 												context,
@@ -371,7 +371,6 @@
 
 pub fn evaluate(context: Context, expr: &LocExpr) -> Result<Val> {
 	use Expr::*;
-	let locexpr = expr.clone();
 	let LocExpr(expr, loc) = expr;
 	Ok(match &**expr {
 		Literal(LiteralType::This) => Val::Obj(
@@ -394,7 +393,7 @@
 		Num(v) => Val::Num(*v),
 		BinaryOp(v1, o, v2) => evaluate_binary_op_special(context, &v1, *o, &v2)?,
 		UnaryOp(o, v) => evaluate_unary_op(*o, &evaluate(context, v)?)?,
-		Var(name) => push(locexpr, "var".to_owned(), || {
+		Var(name) => push(loc, "var", || {
 			Val::Lazy(context.binding(&name)?).unwrap_if_lazy()
 		})?,
 		Index(LocExpr(v, _), index) if matches!(&**v, Expr::Literal(LiteralType::Super)) => {
@@ -733,7 +732,7 @@
 					if *tailstrict {
 						body()?
 					} else {
-						push(locexpr, "function call".to_owned(), body)?
+						push(loc, "function call", body)?
 					}
 				}
 				_ => panic!("{:?} is not a function", value),
@@ -741,16 +740,12 @@
 		}
 		Function(params, body) => evaluate_method(context, params.clone(), body.clone()),
 		AssertExpr(AssertStmt(value, msg), returned) => {
-			let assertion_result = push(value.clone(), "assertion condition".to_owned(), || {
+			let assertion_result = push(&value.1, "assertion condition", || {
 				evaluate(context.clone(), &value)?
 					.try_cast_bool("assertion condition should be boolean")
 			})?;
 			if assertion_result {
-				push(
-					returned.clone(),
-					"assert 'return' branch".to_owned(),
-					|| evaluate(context, returned),
-				)?
+				evaluate(context, returned)?
 			} else if let Some(msg) = msg {
 				panic!(
 					"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();