Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add backtrace context for the evaluator #1200

Merged
merged 1 commit into from
Apr 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 19 additions & 1 deletion kclvm/evaluator/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::rc::Rc;
use generational_arena::Index;
use kclvm_ast::ast;
use kclvm_error::Handler;
use kclvm_runtime::MAIN_PKG_PATH;
use kclvm_runtime::{BacktraceFrame, MAIN_PKG_PATH};

use crate::{
error as kcl_error,
Expand Down Expand Up @@ -229,4 +229,22 @@ impl<'ctx> Evaluator<'ctx> {
proxy: Proxy::Rule(rule),
}))
}

pub(crate) fn push_backtrace(&self, frame: &Frame) {
let ctx = &mut self.runtime_ctx.borrow_mut();
if ctx.cfg.debug_mode {
let backtrace_frame = BacktraceFrame::from_panic_info(&ctx.panic_info);
ctx.backtrace.push(backtrace_frame);
ctx.panic_info.kcl_func = frame.proxy.get_name();
}
}

pub(crate) fn pop_backtrace(&self) {
let ctx = &mut self.runtime_ctx.borrow_mut();
if ctx.cfg.debug_mode {
if let Some(backtrace_frame) = ctx.backtrace.pop() {
ctx.panic_info.kcl_func = backtrace_frame.func;
}
}
}
}
2 changes: 2 additions & 0 deletions kclvm/evaluator/src/func.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ impl<'ctx> Evaluator<'ctx> {
.clone()
};
self.push_pkgpath(&frame.pkgpath);
self.push_backtrace(&frame);
let value = match &frame.proxy {
Proxy::Lambda(lambda) => (lambda.body)(self, &lambda.ctx, args, kwargs),
Proxy::Schema(schema) => {
Expand All @@ -69,6 +70,7 @@ impl<'ctx> Evaluator<'ctx> {
}
Proxy::Rule(rule) => (rule.body)(self, &rule.ctx, args, kwargs),
};
self.pop_backtrace();
self.pop_pkgpath();
value
}
Expand Down
4 changes: 4 additions & 0 deletions kclvm/evaluator/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -919,22 +919,26 @@ impl<'ctx> TypedResultWalker<'ctx> for Evaluator<'ctx> {
};
if let Proxy::Schema(schema) = &frame.proxy {
self.push_pkgpath(&frame.pkgpath);
self.push_backtrace(&frame);
// Set new schema and config
{
let mut ctx = schema.ctx.borrow_mut();
ctx.reset_with_config(config_value, config_meta);
}
let value = (schema.body)(self, &schema.ctx, &list_value, &dict_value);
self.pop_backtrace();
self.pop_pkgpath();
value
} else if let Proxy::Rule(rule) = &frame.proxy {
self.push_pkgpath(&frame.pkgpath);
self.push_backtrace(&frame);
// Set new rule and config
{
let mut ctx = rule.ctx.borrow_mut();
ctx.reset_with_config(config_value, config_meta);
}
let value = (rule.body)(self, &rule.ctx, &list_value, &dict_value);
self.pop_backtrace();
self.pop_pkgpath();
value
} else {
Expand Down
21 changes: 21 additions & 0 deletions kclvm/evaluator/src/proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ pub enum Proxy {
Rule(RuleCaller),
}

impl Proxy {
/// Get the name of the proxy, if it is an anonymous function, returns "lambda"
/// if it is a schema or rule, returns its name.
#[inline]
pub fn get_name(&self) -> String {
match self {
Proxy::Lambda(_) => "lambda".to_string(),
Proxy::Schema(s) => s.ctx.borrow().node.name.node.to_string(),
Proxy::Rule(r) => r.ctx.borrow().node.name.node.to_string(),
}
}
}

/// Call the associated schemas including parent schema and mixin schema
pub(crate) fn call_schema_body(
s: &Evaluator,
Expand All @@ -39,10 +52,12 @@ pub(crate) fn call_schema_body(
};
if let Proxy::Schema(schema) = &frame.proxy {
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
{
schema.ctx.borrow_mut().set_info_with_schema(&ctx.borrow())
}
let value = (schema.body)(s, &schema.ctx, args, kwargs);
s.pop_backtrace();
s.pop_pkgpath();
value
} else {
Expand Down Expand Up @@ -71,10 +86,12 @@ pub(crate) fn call_schema_body_from_rule(
};
if let Proxy::Schema(schema) = &frame.proxy {
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
{
schema.ctx.borrow_mut().set_info_with_rule(&ctx.borrow())
}
let value = (schema.body)(s, &schema.ctx, args, kwargs);
s.pop_backtrace();
s.pop_pkgpath();
value
} else {
Expand Down Expand Up @@ -102,10 +119,12 @@ pub(crate) fn call_schema_check(
};
if let Proxy::Schema(schema) = &frame.proxy {
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
if let Some(ctx) = ctx {
schema.ctx.borrow_mut().set_info_with_schema(&ctx.borrow())
}
(schema.check)(s, &schema.ctx, args, kwargs);
s.pop_backtrace();
s.pop_pkgpath();
}
}
Expand All @@ -122,7 +141,9 @@ pub(crate) fn call_rule_check(s: &Evaluator, func: &ValueRef, args: &ValueRef, k
};
if let Proxy::Rule(rule) = &frame.proxy {
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
(rule.check)(s, &rule.ctx, args, kwargs);
s.pop_backtrace();
s.pop_pkgpath();
}
}
Expand Down
2 changes: 2 additions & 0 deletions kclvm/evaluator/src/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -593,7 +593,9 @@ pub(crate) fn schema_check(
};
if let Proxy::Schema(schema) = &frame.proxy {
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
(schema.check)(s, &schema.ctx, args, kwargs);
s.pop_backtrace();
s.pop_pkgpath();
}
}
Expand Down
4 changes: 4 additions & 0 deletions kclvm/evaluator/src/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@ pub fn resolve_schema(s: &Evaluator, schema: &ValueRef, keys: &[String]) -> Valu
};
let schema = if let Proxy::Schema(caller) = &frame.proxy {
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
// Set new schema and config
{
let mut ctx = caller.ctx.borrow_mut();
ctx.reset_with_config(config_value, config_meta);
}
let value = (caller.body)(s, &caller.ctx, &schema_value.args, &schema_value.kwargs);
s.pop_backtrace();
s.pop_pkgpath();
value
} else {
Expand Down Expand Up @@ -157,12 +159,14 @@ pub fn convert_collection_value(s: &Evaluator, value: &ValueRef, tpe: &str) -> V
return value.clone();
}
s.push_pkgpath(&frame.pkgpath);
s.push_backtrace(&frame);
// Set new schema and config
{
let mut ctx = caller.ctx.borrow_mut();
ctx.reset_with_config(value.clone(), config_meta);
}
let value = (caller.body)(s, &caller.ctx, &s.list_value(), &s.dict_value());
s.pop_backtrace();
s.pop_pkgpath();
value
} else {
Expand Down
Loading