Skip to content
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
21 changes: 15 additions & 6 deletions kclvm/compiler/src/codegen/llvm/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,28 +418,31 @@ impl<'ctx> ValueMethods for LLVMCodeGenContext<'ctx> {
}
/// Construct a function value using a native function.
fn function_value(&self, function: FunctionValue<'ctx>) -> Self::Value {
let func_name = function.get_name().to_str().unwrap();
let func_name_ptr = self.native_global_string(func_name, func_name).into();
let lambda_fn_ptr = self.builder.build_bitcast(
function.as_global_value().as_pointer_value(),
self.context.i64_type().ptr_type(AddressSpace::default()),
"",
);
self.build_call(
&ApiFunc::kclvm_value_Function_using_ptr.name(),
&[lambda_fn_ptr],
&[lambda_fn_ptr, func_name_ptr],
)
}
/// Construct a closure function value with the closure variable.
fn closure_value(&self, function: FunctionValue<'ctx>, closure: Self::Value) -> Self::Value {
let func_name = function.get_name().to_str().unwrap();
let func_name_ptr = self.native_global_string(func_name, func_name).into();
// Convert the function to a i64 pointer to store it into the function value.
let fn_ptr = self.builder.build_bitcast(
function.as_global_value().as_pointer_value(),
self.context.i64_type().ptr_type(AddressSpace::default()),
"",
);
let name = self.native_global_string("", "").into();
self.build_call(
&ApiFunc::kclvm_value_Function.name(),
&[fn_ptr, closure, name],
&[fn_ptr, closure, func_name_ptr, self.native_i8_zero().into()],
)
}
/// Construct a schema function value using native functions.
Expand Down Expand Up @@ -1674,11 +1677,17 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
self.context.i64_type().ptr_type(AddressSpace::default()),
"",
);
let name = self.native_global_string("", "").into();
let func_name = function.get_name().to_str().unwrap();
let func_name_ptr = self.native_global_string(func_name, func_name).into();
let none_value = self.none_value();
self.build_call(
&ApiFunc::kclvm_value_Function.name(),
&[lambda_fn_ptr, none_value, name],
&[
lambda_fn_ptr,
none_value,
func_name_ptr,
self.native_i8_zero().into(),
],
)
};
Ok(value)
Expand All @@ -1696,7 +1705,7 @@ impl<'ctx> LLVMCodeGenContext<'ctx> {
let none_value = self.none_value();
return Ok(self.build_call(
&ApiFunc::kclvm_value_Function.name(),
&[null_fn_ptr, none_value, name],
&[null_fn_ptr, none_value, name, self.native_i8(1).into()],
));
// User pkgpath
} else {
Expand Down
5 changes: 3 additions & 2 deletions kclvm/error/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,13 +96,14 @@ impl From<Loc> for Position {

impl Diagnostic {
pub fn new(level: Level, message: &str, pos: Position) -> Self {
Diagnostic::new_with_code(level, message, pos, None)
Diagnostic::new_with_code(level, message, None, pos, None)
}

/// New a diagnostic with error code.
pub fn new_with_code(
level: Level,
message: &str,
note: Option<&str>,
pos: Position,
code: Option<DiagnosticId>,
) -> Self {
Expand All @@ -112,7 +113,7 @@ impl Diagnostic {
pos,
style: Style::LineAndColumn,
message: message.to_string(),
note: None,
note: note.map(|s| s.to_string()),
}],
code,
}
Expand Down
66 changes: 51 additions & 15 deletions kclvm/error/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ impl Handler {
let diag = Diagnostic::new_with_code(
Level::Error,
&message,
None,
pos,
Some(DiagnosticId::Error(E1001.kind)),
);
Expand All @@ -109,6 +110,7 @@ impl Handler {
let diag = Diagnostic::new_with_code(
Level::Error,
msg,
None,
pos,
Some(DiagnosticId::Error(E2G22.kind)),
);
Expand All @@ -122,6 +124,7 @@ impl Handler {
let diag = Diagnostic::new_with_code(
Level::Error,
msg,
None,
pos,
Some(DiagnosticId::Error(E2L23.kind)),
);
Expand Down Expand Up @@ -207,7 +210,7 @@ impl Handler {
/// ```
/// use kclvm_error::*;
/// let mut handler = Handler::default();
/// handler.add_diagnostic(Diagnostic::new_with_code(Level::Error, "error message", Position::dummy_pos(), Some(DiagnosticId::Error(E1001.kind))));
/// handler.add_diagnostic(Diagnostic::new_with_code(Level::Error, "error message", None, Position::dummy_pos(), Some(DiagnosticId::Error(E1001.kind))));
/// ```
#[inline]
pub fn add_diagnostic(&mut self, diagnostic: Diagnostic) -> &mut Self {
Expand All @@ -219,26 +222,58 @@ impl Handler {

impl From<PanicInfo> for Diagnostic {
fn from(panic_info: PanicInfo) -> Self {
let mut diag = Diagnostic::new_with_code(
Level::Error,
if panic_info.kcl_arg_msg.is_empty() {
&panic_info.message
} else {
&panic_info.kcl_arg_msg
},
Position {
filename: panic_info.kcl_file.clone(),
line: panic_info.kcl_line as u64,
column: None,
},
Some(DiagnosticId::Error(E3M38.kind)),
);
let panic_msg = if panic_info.kcl_arg_msg.is_empty() {
&panic_info.message
} else {
&panic_info.kcl_arg_msg
};

let mut diag = if panic_info.backtrace.is_empty() {
Diagnostic::new_with_code(
Level::Error,
&panic_msg,
None,
Position {
filename: panic_info.kcl_file.clone(),
line: panic_info.kcl_line as u64,
column: None,
},
Some(DiagnosticId::Error(E3M38.kind)),
)
} else {
let mut backtrace_msg = "backtrace:\n".to_string();
let mut backtrace = panic_info.backtrace.clone();
backtrace.reverse();
for (index, frame) in backtrace.iter().enumerate() {
backtrace_msg.push_str(&format!(
"\t{index}: {}\n\t\tat {}:{}",
frame.func, frame.file, frame.line
));
if frame.col != 0 {
backtrace_msg.push_str(&format!(":{}", frame.col))
}
backtrace_msg.push_str("\n")
}
Diagnostic::new_with_code(
Level::Error,
&panic_msg,
Some(&backtrace_msg),
Position {
filename: panic_info.kcl_file.clone(),
line: panic_info.kcl_line as u64,
column: None,
},
Some(DiagnosticId::Error(E3M38.kind)),
)
};

if panic_info.kcl_config_meta_file.is_empty() {
return diag;
}
let mut config_meta_diag = Diagnostic::new_with_code(
Level::Error,
&panic_info.kcl_config_meta_arg_msg,
None,
Position {
filename: panic_info.kcl_config_meta_file.clone(),
line: panic_info.kcl_config_meta_line as u64,
Expand Down Expand Up @@ -297,6 +332,7 @@ impl ParseError {
Ok(Diagnostic::new_with_code(
Level::Error,
&self.to_string(),
None,
loc.into(),
Some(DiagnosticId::Error(ErrorKind::InvalidSyntax)),
))
Expand Down
Binary file modified kclvm/runtime/src/_kclvm.bc
Binary file not shown.
4 changes: 2 additions & 2 deletions kclvm/runtime/src/_kclvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,9 +566,9 @@ kclvm_value_ref_t* kclvm_value_Float(kclvm_float_t v);

kclvm_float_t* kclvm_value_Float_ptr(kclvm_value_ref_t* p);

kclvm_value_ref_t* kclvm_value_Function(uint64_t* fn_ptr, kclvm_value_ref_t* closure, kclvm_char_t* external_name);
kclvm_value_ref_t* kclvm_value_Function(uint64_t* fn_ptr, kclvm_value_ref_t* closure, kclvm_char_t* name, kclvm_bool_t is_external);

kclvm_value_ref_t* kclvm_value_Function_using_ptr(uint64_t* fn_ptr);
kclvm_value_ref_t* kclvm_value_Function_using_ptr(uint64_t* fn_ptr, kclvm_char_t* name);

kclvm_value_ref_t* kclvm_value_Int(kclvm_int_t v);

Expand Down
4 changes: 2 additions & 2 deletions kclvm/runtime/src/_kclvm.ll
Original file line number Diff line number Diff line change
Expand Up @@ -514,9 +514,9 @@ declare %kclvm_value_ref_t* @kclvm_value_Float(%kclvm_float_t %v);

declare %kclvm_float_t* @kclvm_value_Float_ptr(%kclvm_value_ref_t* %p);

declare %kclvm_value_ref_t* @kclvm_value_Function(i64* %fn_ptr, %kclvm_value_ref_t* %closure, %kclvm_char_t* %external_name);
declare %kclvm_value_ref_t* @kclvm_value_Function(i64* %fn_ptr, %kclvm_value_ref_t* %closure, %kclvm_char_t* %name, %kclvm_bool_t %is_external);

declare %kclvm_value_ref_t* @kclvm_value_Function_using_ptr(i64* %fn_ptr);
declare %kclvm_value_ref_t* @kclvm_value_Function_using_ptr(i64* %fn_ptr, %kclvm_char_t* %name);

declare %kclvm_value_ref_t* @kclvm_value_Int(%kclvm_int_t %v);

Expand Down
10 changes: 5 additions & 5 deletions kclvm/runtime/src/_kclvm_api_spec.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright 2022 The KCL Authors. All rights reserved.
// Copyright 2023 The KCL Authors. All rights reserved.

// Auto generated by <make gen-api-spec> command, DONOT EDIT!!!

Expand Down Expand Up @@ -271,12 +271,12 @@
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_schema_with_config(%kclvm_value_ref_t* %schema_dict, %kclvm_value_ref_t* %config, %kclvm_value_ref_t* %config_meta, %kclvm_char_t* %name, %kclvm_char_t* %pkgpath, %kclvm_value_ref_t* %is_sub_schema, %kclvm_value_ref_t* %record_instance, %kclvm_value_ref_t* %instance_pkgpath, %kclvm_value_ref_t* %optional_mapping);

// api-spec: kclvm_value_Function
// api-spec(c): kclvm_value_ref_t* kclvm_value_Function(uint64_t* fn_ptr, kclvm_value_ref_t* closure, kclvm_char_t* external_name);
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_Function(i64* %fn_ptr, %kclvm_value_ref_t* %closure, %kclvm_char_t* %external_name);
// api-spec(c): kclvm_value_ref_t* kclvm_value_Function(uint64_t* fn_ptr, kclvm_value_ref_t* closure, kclvm_char_t* name, kclvm_bool_t is_external);
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_Function(i64* %fn_ptr, %kclvm_value_ref_t* %closure, %kclvm_char_t* %name, %kclvm_bool_t %is_external);

// api-spec: kclvm_value_Function_using_ptr
// api-spec(c): kclvm_value_ref_t* kclvm_value_Function_using_ptr(uint64_t* fn_ptr);
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_Function_using_ptr(i64* %fn_ptr);
// api-spec(c): kclvm_value_ref_t* kclvm_value_Function_using_ptr(uint64_t* fn_ptr, kclvm_char_t* name);
// api-spec(llvm): declare %kclvm_value_ref_t* @kclvm_value_Function_using_ptr(i64* %fn_ptr, %kclvm_char_t* %name);

// api-spec: kclvm_value_schema_function
// api-spec(c): kclvm_value_ref_t* kclvm_value_schema_function(uint64_t* fn_ptr, uint64_t* check_fn_ptr, kclvm_char_t* tpe);
Expand Down
39 changes: 38 additions & 1 deletion kclvm/runtime/src/api/kclvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,9 @@ pub struct FuncValue {
pub fn_ptr: u64,
pub check_fn_ptr: u64,
pub closure: ValueRef,
pub external_name: String,
pub name: String,
pub runtime_type: String,
pub is_external: bool,
}

#[derive(PartialEq, Clone, Default, Debug)]
Expand All @@ -293,13 +294,15 @@ pub struct OptionHelp {
#[derive(PartialEq, Eq, Clone, Default, Debug, Serialize, Deserialize)]
pub struct PanicInfo {
pub __kcl_PanicInfo__: bool, // "__kcl_PanicInfo__"
pub backtrace: Vec<BacktraceFrame>,

pub rust_file: String,
pub rust_line: i32,
pub rust_col: i32,

pub kcl_pkgpath: String,
pub kcl_file: String,
pub kcl_func: String,
pub kcl_line: i32,
pub kcl_col: i32,
pub kcl_arg_msg: String,
Expand Down Expand Up @@ -368,6 +371,7 @@ pub struct Context {

pub main_pkg_path: String,
pub main_pkg_files: Vec<String>,
pub backtrace: Vec<BacktraceFrame>,

pub imported_pkgpath: HashSet<String>,
pub app_args: HashMap<String, u64>,
Expand All @@ -385,10 +389,43 @@ pub struct Context {
pub objects: IndexSet<usize>,
}

#[derive(PartialEq, Eq, Clone, Debug, Serialize, Deserialize)]
pub struct BacktraceFrame {
pub file: String,
pub func: String,
pub col: i32,
pub line: i32,
}
impl Default for BacktraceFrame {
fn default() -> Self {
Self {
file: Default::default(),
func: "_kclvm_main".to_string(),
col: Default::default(),
line: Default::default(),
}
}
}

impl BacktraceFrame {
pub fn from_panic_info(info: &PanicInfo) -> Self {
Self {
file: info.kcl_file.clone(),
func: info.kcl_func.clone(),
col: info.kcl_col,
line: info.kcl_line,
}
}
}

impl Context {
pub fn new() -> Self {
Context {
instances: RefCell::new(HashMap::new()),
panic_info: PanicInfo {
kcl_func: "kclvm_main".to_string(),
..Default::default()
},
..Default::default()
}
}
Expand Down
22 changes: 15 additions & 7 deletions kclvm/runtime/src/context/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ pub mod api;
pub use api::*;
use std::fmt;

use crate::PanicInfo;
use crate::{BacktraceFrame, PanicInfo};

#[allow(non_camel_case_types)]
type kclvm_value_ref_t = crate::ValueRef;
Expand Down Expand Up @@ -189,16 +189,24 @@ impl crate::Context {
pub fn set_panic_info(&mut self, info: &std::panic::PanicInfo) {
self.panic_info.__kcl_PanicInfo__ = true;

if let Some(s) = info.payload().downcast_ref::<&str>() {
self.panic_info.message = s.to_string();
self.panic_info.message = if let Some(s) = info.payload().downcast_ref::<&str>() {
s.to_string()
} else if let Some(s) = info.payload().downcast_ref::<&String>() {
self.panic_info.message = (*s).clone();
(*s).clone()
} else if let Some(s) = info.payload().downcast_ref::<String>() {
self.panic_info.message = (*s).clone();
(*s).clone()
} else {
self.panic_info.message = "".to_string();
"".to_string()
};
if self.cfg.debug_mode {
self.panic_info.backtrace = self.backtrace.clone();
self.panic_info.backtrace.push(BacktraceFrame {
file: self.panic_info.kcl_file.clone(),
func: self.panic_info.kcl_func.clone(),
col: self.panic_info.kcl_col,
line: self.panic_info.kcl_line,
});
}

if let Some(location) = info.location() {
self.panic_info.rust_file = location.file().to_string();
self.panic_info.rust_line = location.line() as i32;
Expand Down
Loading