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
43 changes: 36 additions & 7 deletions rust/src/interfaces/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ pub struct LightVM {
pub backtrace: bool,
pub explain: bool,
pub hint: bool,
pub diagnostic_links: bool,
}
impl LightVM {
pub fn new_node(
Expand All @@ -82,6 +83,7 @@ impl LightVM {
backtrace: bool,
explain: bool,
hint: bool,
diagnostic_links: bool,
) -> Self {
use crate::types::value::Value;
use crate::types::vmstate::VmState;
Expand Down Expand Up @@ -114,6 +116,7 @@ impl LightVM {
backtrace,
explain,
hint,
diagnostic_links,
}
}
#[inline(always)]
Expand All @@ -126,8 +129,13 @@ impl LightVM {
}
Ok(())
}
pub fn set_mode(&self, backtrace: bool, explain: bool, hint: bool) {
crate::modules::vmerror::config::set_thread_error_config(backtrace, explain, hint);
pub fn set_mode(&self, backtrace: bool, explain: bool, hint: bool, diagnostic_links: bool) {
crate::modules::vmerror::config::set_thread_error_config(
backtrace,
explain,
hint,
diagnostic_links,
);
}
pub fn index_metadata(&mut self) {
self.functions.clear();
Expand Down Expand Up @@ -169,7 +177,12 @@ impl LightVM {
get_versions()
}
pub fn load_internal(&mut self, source: String) -> Result<(), VMError> {
self.set_mode(self.backtrace, self.explain, self.hint);
self.set_mode(
self.backtrace,
self.explain,
self.hint,
self.diagnostic_links,
);
crate::modules::vmerror::get_backtrace::clear_backtrace();
if self.backtrace {
crate::modules::vmerror::get_backtrace::capture_backtrace();
Expand Down Expand Up @@ -229,7 +242,12 @@ impl LightVM {
Ok(())
}
pub fn run_internal(&mut self, options: Option<RunOptions>) -> Result<String, VMError> {
self.set_mode(self.backtrace, self.explain, self.hint);
self.set_mode(
self.backtrace,
self.explain,
self.hint,
self.diagnostic_links,
);
crate::modules::vmerror::get_backtrace::clear_backtrace();
if self.backtrace {
crate::modules::vmerror::get_backtrace::capture_backtrace();
Expand Down Expand Up @@ -280,7 +298,12 @@ impl LightVM {
}
#[inline]
pub fn compile_internal(&mut self, config: CompileConfig) -> Result<(), VMError> {
self.set_mode(self.backtrace, self.explain, self.hint);
self.set_mode(
self.backtrace,
self.explain,
self.hint,
self.diagnostic_links,
);
crate::modules::vmerror::get_backtrace::clear_backtrace();
if self.backtrace {
crate::modules::vmerror::get_backtrace::capture_backtrace();
Expand Down Expand Up @@ -498,7 +521,12 @@ impl LightVM {
bytecode_raw: serde_json::Value,
) -> Result<String, VMError> {
self.require(Capability::Control)?;
self.set_mode(self.backtrace, self.explain, self.hint);
self.set_mode(
self.backtrace,
self.explain,
self.hint,
self.diagnostic_links,
);
crate::modules::vmerror::get_backtrace::clear_backtrace();
if self.backtrace {
crate::modules::vmerror::get_backtrace::capture_backtrace();
Expand Down Expand Up @@ -642,6 +670,7 @@ mod tests {
backtrace: false,
explain: false,
hint: true,
diagnostic_links: true,
}
}
#[test]
Expand Down Expand Up @@ -904,7 +933,7 @@ mod tests {
vm.backtrace = true;
vm.explain = true;
vm.hint = false;
set_thread_error_config(false, false, true);
set_thread_error_config(false, false, true, true);
let before = get_thread_or_global_config();
let result = vm.optimize_bytecode_internal(serde_json::json!([["noop"]]));
let after = get_thread_or_global_config();
Expand Down
27 changes: 27 additions & 0 deletions rust/src/interfaces/napi_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ impl NodeLightVM {
backtrace: error_options.backtrace.unwrap_or(false),
explain: error_options.explain.unwrap_or(false),
hint: error_options.hint.unwrap_or(true),
diagnostic_links: error_options.diagnostic_links.unwrap_or(true),
},
})
}
Expand Down Expand Up @@ -187,6 +188,11 @@ impl NodeLightVM {
self.inner.hint = enabled;
Ok(())
}
#[napi(js_name = "withDiagnosticLinks")]
pub fn with_diagnostic_links(&mut self, enabled: bool) -> Result<()> {
self.inner.diagnostic_links = enabled;
Ok(())
}
#[napi]
pub fn info(&mut self) -> Result<JSInfoVM> {
let info_vm = self.inner.info_internal();
Expand Down Expand Up @@ -561,6 +567,7 @@ impl NodeLightVM {
is_backtrace,
is_explain,
is_hint,
self.inner.diagnostic_links,
);
vm_instance.caps = self
.inner
Expand Down Expand Up @@ -599,6 +606,7 @@ impl NodeLightVM {
#[cfg(test)]
mod tests {
use super::*;
use crate::types::js::js_error_options::JSErrorOptions;
#[test]
fn unknown_capability_uses_vm_error_display() {
let config = VmNapiConfig {
Expand Down Expand Up @@ -717,4 +725,23 @@ mod tests {
r#"[["stop"]]"#
);
}
#[test]
fn diagnostic_links_can_be_configured_and_updated() {
let mut vm = NodeLightVM::napi_new(VmNapiConfig {
error_options: Some(JSErrorOptions {
diagnostic_links: Some(false),
..Default::default()
}),
..Default::default()
})
.expect("expected a VM");

assert!(!vm.inner.diagnostic_links);
vm.with_diagnostic_links(true)
.expect("expected the setting to update");
assert!(vm.inner.diagnostic_links);
vm.with_diagnostic_links(false)
.expect("expected the setting to update");
assert!(!vm.inner.diagnostic_links);
}
}
19 changes: 19 additions & 0 deletions rust/src/interfaces/native_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ impl LightVM {
backtrace: error_options.backtrace,
explain: error_options.explain,
hint: error_options.hint,
diagnostic_links: error_options.diagnostic_links,
}
}
pub fn set_max_io(mut self, value: usize) -> Self {
Expand Down Expand Up @@ -283,6 +284,10 @@ impl LightVM {
self.hint = enabled;
self
}
pub fn with_diagnostic_links(mut self, enabled: bool) -> Self {
self.diagnostic_links = enabled;
self
}
#[cfg(not(feature = "wasm"))]
pub fn info(&mut self) -> InfoVM {
self.info_internal()
Expand Down Expand Up @@ -464,6 +469,7 @@ impl LightVM {
backtrace: self.backtrace,
explain: self.explain,
hint: self.hint,
diagnostic_links: self.diagnostic_links,
time_budget: self.time_budget,
can_control: self.caps.contains(&Capability::Control),
can_debug: self.caps.contains(&Capability::Debug),
Expand All @@ -475,6 +481,7 @@ pub struct LightVMTools {
pub backtrace: bool,
pub explain: bool,
pub hint: bool,
pub diagnostic_links: bool,
pub time_budget: TimeBudget,
pub can_control: bool,
pub can_debug: bool,
Expand Down Expand Up @@ -534,6 +541,7 @@ impl LightVMTools {
backtrace: self.backtrace,
explain: self.explain,
hint: self.hint,
diagnostic_links: self.diagnostic_links,
}),
};
let opt_str = LightVM::new(config)
Expand Down Expand Up @@ -628,6 +636,15 @@ mod tests {
assert_eq!(vm.state, VmState::Idle);
}
#[test]
fn diagnostic_links_can_be_disabled() {
let mut vm = LightVM::new(VmConfig::default()).with_diagnostic_links(false);
let error = vm
.load_internal("invalid source".to_string())
.expect_err("expected invalid source to fail");

assert!(!error.to_string().contains("documentation:"));
}
#[test]
fn on_registers_listener() {
let config = VmConfig {
caps: vec![],
Expand Down Expand Up @@ -818,6 +835,7 @@ mod tests {
backtrace: tools.backtrace,
explain: tools.explain,
hint: tools.hint,
diagnostic_links: tools.diagnostic_links,
}),
..Default::default()
});
Expand Down Expand Up @@ -845,6 +863,7 @@ mod tests {
backtrace: tools.backtrace,
explain: tools.explain,
hint: tools.hint,
diagnostic_links: tools.diagnostic_links,
}),
..Default::default()
});
Expand Down
22 changes: 20 additions & 2 deletions rust/src/interfaces/wasm_interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ impl WasmLightVM {
backtrace: error_options.backtrace.unwrap_or(false),
explain: error_options.explain.unwrap_or(false),
hint: error_options.hint.unwrap_or(true),
diagnostic_links: error_options.diagnostic_links.unwrap_or(true),
},
})
}
Expand Down Expand Up @@ -173,6 +174,10 @@ impl WasmLightVM {
pub fn with_hint(&mut self, enabled: bool) {
self.inner.hint = enabled;
}
#[wasm_bindgen(js_name = "withDiagnosticLinks")]
pub fn with_diagnostic_links(&mut self, enabled: bool) {
self.inner.diagnostic_links = enabled;
}
#[wasm_bindgen]
pub fn load(&mut self, source: String) -> Result<(), JsValue> {
self
Expand Down Expand Up @@ -384,6 +389,7 @@ impl WasmLightVM {
backtrace: self.inner.backtrace,
explain: self.inner.explain,
hint: self.inner.hint,
diagnostic_links: self.inner.diagnostic_links,
time_budget: self.inner.time_budget,
can_observe: self.inner.caps.contains(&Capability::Observe),
can_control: self.inner.caps.contains(&Capability::Control),
Expand All @@ -398,6 +404,7 @@ pub struct WasmLightVMTools {
pub backtrace: bool,
pub explain: bool,
pub hint: bool,
pub diagnostic_links: bool,
time_budget: TimeBudget,
pub can_observe: bool,
pub can_control: bool,
Expand All @@ -417,6 +424,7 @@ impl WasmLightVMTools {
self.backtrace,
self.explain,
self.hint,
self.diagnostic_links,
);
vm_instance.caps = {
let mut caps = HashSet::new();
Expand Down Expand Up @@ -506,7 +514,7 @@ mod tests {
use super::*;
use crate::types::security_config::SecurityConfig;
fn vm_with_control_capability() -> WasmLightVM {
let mut inner = LightVM::new_node(SecurityConfig::default(), false, false, false, true);
let mut inner = LightVM::new_node(SecurityConfig::default(), false, false, false, true, true);
inner.caps.insert(Capability::Control);
WasmLightVM { inner }
}
Expand All @@ -515,10 +523,14 @@ mod tests {
let json_data = serde_json::json!({
"caps": [0, 2],
"runtimeConfig": { "nightly": true },
"errorOptions": { "hint": true }
"errorOptions": { "hint": true, "diagnosticLinks": false }
});
let config: VmWasmConfig = serde_json::from_value(json_data).unwrap();
assert_eq!(config.caps, vec![0, 2]);
assert_eq!(
config.error_options.as_ref().unwrap().diagnostic_links,
Some(false)
);
#[cfg(target_arch = "wasm32")]
{
let mut vm = WasmLightVM::new(serde_wasm_bindgen::to_value(&config).unwrap()).unwrap();
Expand All @@ -530,6 +542,12 @@ mod tests {
assert_eq!(config.runtime_config.unwrap().nightly, Some(true));
}
#[test]
fn diagnostic_links_can_be_updated() {
let mut vm = vm_with_control_capability();
vm.with_diagnostic_links(false);
assert!(!vm.inner.diagnostic_links);
}
#[test]
fn start_and_finish_event_names_are_supported() {
assert_eq!(parse_event("start"), Some(VmEvent::Start));
assert_eq!(parse_event("finish"), Some(VmEvent::Finish));
Expand Down
6 changes: 5 additions & 1 deletion rust/src/modules/vmerror/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ pub struct VMErrorContainer {
pub backtrace: bool,
pub explain: bool,
pub hint: bool,
pub diagnostic_links: bool,
}
impl Default for VMErrorContainer {
fn default() -> Self {
Expand All @@ -27,26 +28,29 @@ impl VMErrorContainer {
backtrace: false,
explain: false,
hint: true,
diagnostic_links: true,
}
}
pub fn get_value(&self) -> VMErrorContainer {
VMErrorContainer {
backtrace: self.backtrace,
explain: self.explain,
hint: self.hint,
diagnostic_links: self.diagnostic_links,
}
}
}
thread_local! {
static THREAD_ERROR_CONFIG: RefCell<Option<VMErrorContainer>> = const { RefCell::new(None) };
}
static EXPLAIN_MODE: OnceLock<Mutex<VMErrorContainer>> = OnceLock::new();
pub fn set_thread_error_config(backtrace: bool, explain: bool, hint: bool) {
pub fn set_thread_error_config(backtrace: bool, explain: bool, hint: bool, diagnostic_links: bool) {
THREAD_ERROR_CONFIG.with(|config| {
*config.borrow_mut() = Some(VMErrorContainer {
backtrace,
explain,
hint,
diagnostic_links,
});
});
}
Expand Down
13 changes: 8 additions & 5 deletions rust/src/modules/vmerror/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ impl fmt::Display for VMError {
let is_backtrace = config.backtrace;
let is_explain = config.explain;
let is_hint = config.hint;
let diagnostic_links = config.diagnostic_links;
let err_type = match self {
VMError::StackOverflow { .. } => "StackOverflow",
VMError::StackUnderflow { .. } => "StackUnderflow",
Expand Down Expand Up @@ -143,11 +144,13 @@ impl fmt::Display for VMError {
write!(f, "\n {DARK_GRAY}error type: {}", err_type)?;
}
}
write!(
f,
"\n {RESET}{CYAN}├── {DARK_GRAY}documentation: {}{RESET}",
self.diagnostic_link()
)?;
if diagnostic_links {
write!(
f,
"\n {RESET}{CYAN}├── {DARK_GRAY}documentation: {}{RESET}",
self.diagnostic_link()
)?;
}
if is_backtrace {
let backtrace = get_backtrace();
write!(
Expand Down
Loading
Loading