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(Compiler-Base): Reuse kclvm emitter #154

Merged
merged 19 commits into from
Aug 23, 2022
5 changes: 4 additions & 1 deletion kclvm/compiler_base/3rdparty/rustc_errors/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
termcolor = "1.0"
termcolor = "1.0"

[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["handleapi", "synchapi", "winbase"] }
7 changes: 4 additions & 3 deletions kclvm/compiler_base/3rdparty/rustc_errors/src/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
Porting ['rustc_errors/styled_buffer.rs'] code here to enable code reuse due to the unstable and unreusable of the ['rustc_errors'] crate now.
We mainly reuse helper structs and functions like `StyledBuffer`, `StyledString` to render text in Compiler-Base.
Porting ['rustc_errors/styled_buffer.rs'] and ['rustc_errors/lock.rs'] code here to enable code reuse due to the unstable and unreusable of the ['rustc_errors'] crate now.
We mainly reuse helper structs and functions like `StyledBuffer`, `StyledString` to render text in Compiler-Base, and reuse helper function `acquire_global_lock` to emit the diagnostic messages.

Note: the structs and functions here exist as implementations and will not be exposed to other crates directly.

Reuse 'styled_buffer.rs' in 'rustc_errors',
Reuse 'styled_buffer.rs' and 'lock.rs' in 'rustc_errors',
and 'styled_buffer.rs' has been modified to fit the feature of 'Compiler-Base'.

We modified some features on porting code:
Expand Down
2 changes: 1 addition & 1 deletion kclvm/compiler_base/3rdparty/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
//!
//! - add some test cases for 'StyledBuffer'.
use termcolor::ColorSpec;

pub mod lock;
zong-zhe marked this conversation as resolved.
Show resolved Hide resolved
pub mod styled_buffer;

/// 'Style' is a trait used to specify the user customize 'XXXStyle' can be accepted by 'StyleBuffer'.
Expand Down
93 changes: 93 additions & 0 deletions kclvm/compiler_base/3rdparty/rustc_errors/src/lock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//! Bindings to acquire a global named lock.
//!
//! This is intended to be used to synchronize multiple compiler processes to
//! ensure that we can output complete errors without interleaving on Windows.
//! Note that this is currently only needed for allowing only one 32-bit MSVC
//! linker to execute at once on MSVC hosts, so this is only implemented for
//! `cfg(windows)`. Also note that this may not always be used on Windows,
//! only when targeting 32-bit MSVC.
//!
//! For more information about why this is necessary, see where this is called.

use std::any::Any;

#[cfg(windows)]
pub fn acquire_global_lock(name: &str) -> Box<dyn Any> {
use std::ffi::CString;
use std::io;

use winapi::shared::ntdef::HANDLE;
use winapi::um::handleapi::CloseHandle;
use winapi::um::synchapi::{CreateMutexA, ReleaseMutex, WaitForSingleObject};
use winapi::um::winbase::{INFINITE, WAIT_ABANDONED, WAIT_OBJECT_0};

struct Handle(HANDLE);

impl Drop for Handle {
fn drop(&mut self) {
unsafe {
CloseHandle(self.0);
}
}
}

struct Guard(Handle);

impl Drop for Guard {
fn drop(&mut self) {
unsafe {
ReleaseMutex((self.0).0);
}
}
}

let cname = CString::new(name).unwrap();
unsafe {
// Create a named mutex, with no security attributes and also not
// acquired when we create it.
//
// This will silently create one if it doesn't already exist, or it'll
// open up a handle to one if it already exists.
let mutex = CreateMutexA(std::ptr::null_mut(), 0, cname.as_ptr());
if mutex.is_null() {
panic!(
"failed to create global mutex named `{}`: {}",
name,
io::Error::last_os_error()
);
}
let mutex = Handle(mutex);

// Acquire the lock through `WaitForSingleObject`.
//
// A return value of `WAIT_OBJECT_0` means we successfully acquired it.
//
// A return value of `WAIT_ABANDONED` means that the previous holder of
// the thread exited without calling `ReleaseMutex`. This can happen,
// for example, when the compiler crashes or is interrupted via ctrl-c
// or the like. In this case, however, we are still transferred
// ownership of the lock so we continue.
//
// If an error happens.. well... that's surprising!
match WaitForSingleObject(mutex.0, INFINITE) {
WAIT_OBJECT_0 | WAIT_ABANDONED => {}
code => {
panic!(
"WaitForSingleObject failed on global mutex named \
`{}`: {} (ret={:x})",
name,
io::Error::last_os_error(),
code
);
}
}

// Return a guard which will call `ReleaseMutex` when dropped.
Box::new(Guard(mutex))
}
}

#[cfg(not(windows))]
pub fn acquire_global_lock(_name: &str) -> Box<dyn Any> {
Box::new(())
}
1 change: 1 addition & 0 deletions kclvm/compiler_base/error/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
compiler_base_macros = {path = "../macros", version = "0.1.0"}
rustc_errors = {path="../3rdparty/rustc_errors", version="0.1.0"}
termcolor = "1.0"
2 changes: 0 additions & 2 deletions kclvm/compiler_base/error/src/diagnostic/components.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
use super::{style::DiagnosticStyle, Component};
use rustc_errors::styled_buffer::StyledBuffer;

use super::{style::DiagnosticStyle, Component};

/// `Label` can be considered as a component of diagnostic to display a short label message in `Diagnositc`.
/// `Label` provides "error", "warning", "note" and "Help" four kinds of labels.
///
Expand Down
4 changes: 2 additions & 2 deletions kclvm/compiler_base/error/src/diagnostic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ pub mod style;
mod tests;

/// 'Component' specifies the method `format()` that all diagnostic components should implement.
///
///
/// 'Component' decouples 'structure' and 'theme' during formatting diagnostic components.
/// `T: Clone + PartialEq + Eq + Style` is responsible for 'theme' such as colors/fonts in the component formatting.
/// `format()` organizes the 'structure' of diagnostic components.
Expand All @@ -31,7 +31,7 @@ where
/// sb.pushs(&self.text, Some(DiagnosticStyle::Logo));
/// }
/// }
///
///
/// ```
fn format(&self, sb: &mut StyledBuffer<T>);
}
Expand Down
Loading