Don't define a panic handler in std::vm

By just using the VM's built-in panic handler (which now produces the
same output) we can simplify std::vm, and we no longer need to import it
in std::prelude.
parent 2e49e503
Pipeline #107058554 passed with stages
in 20 minutes and 27 seconds
......@@ -27,7 +27,6 @@ import std::array::extensions::(self as _)
import std::map::(Map as _Map)
import std::range::(Range as _Range)
import std::vm
# These constants are re-exported so they're available to all modules by
# default. Core types such as String should be exposed in std::globals instead.
......
# Methods for interacting with the Inko virtual machine.
import std::conversion::ToString
import std::debug
import std::process
import std::stdio::stderr
import std::string_buffer::StringBuffer
# Terminates the VM immediately with the given exit status.
#
......@@ -48,42 +43,3 @@ def panicking(block: lambda (String)) -> Nil {
_INKOC.set_default_panic_handler(block)
Nil
}
# Registers the default panic handler.
#
# When this handler is invoked, an error and stacktrace is printed, followed by
# terminating the _entire_ program. The program will be terminated with exit
# status code 1.
panicking lambda (error) {
# We use a single buffer for the entire error, instead of writing to STDERR
# multiple times. This ensures the output does not get messed up by other
# processes writing to STDERR concurrently.
let output =
StringBuffer.new('Stack trace (the most recent call comes last):')
let module_path = _INKOC.current_file_path
debug.stacktrace(skip: 2).each_with_index do (frame, index) {
# If the frame originates from this particular module, we ignore it. This
# way we ignore any frames produced by this handler itself.
(frame.path.to_string == module_path).if_false {
output.push("\n ")
output.push(index.to_string)
output.push(': ')
output.push(frame.path.to_string)
output.push(' line ')
output.push(frame.line.to_string)
output.push(', in ')
output.push(frame.name)
}
}
output.push("\nProcess 0x")
output.push(process.current.identifier.format(radix: 16))
output.push(' panicked: ')
output.push(error)
stderr.print(output)
exit(1)
}
......@@ -3,10 +3,11 @@ use crate::process::RcProcess;
/// Prints a runtime panic to STDERR.
pub fn display_panic(process: &RcProcess, message: &str) {
let mut frames = Vec::new();
let mut buffer = String::new();
for context in process.context().contexts() {
frames.push(format!(
"\"{}\", line {}, in \"{}\"",
"\"{}\" line {}, in \"{}\"",
context.code.file.string_value().unwrap(),
context.line.to_string(),
context.code.name.string_value().unwrap()
......@@ -15,13 +16,17 @@ pub fn display_panic(process: &RcProcess, message: &str) {
frames.reverse();
eprintln!("Stack trace (the most recent call comes last):");
let index_padding = frames.len().to_string().len();
buffer.push_str("Stack trace (the most recent call comes last):");
for (index, line) in frames.iter().enumerate() {
eprintln!(" {}: {}", format!("{:01$}", index, index_padding), line);
buffer.push_str(&format!("\n {}: {}", index, line));
}
eprintln!("Process {:#x} panicked: {}", process.identifier(), message);
buffer.push_str(&format!(
"\nProcess {:#x} panicked: {}",
process.identifier(),
message
));
eprintln!("{}", buffer);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment