go_vm/
lib.rs

1// Copyright 2022 The Goscript Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5//! This crate is part of the Goscript project. Please refer to <https://goscript.dev> for more information.
6//!
7//! # Feature
8//! - `async`: Channel and goroutine support
9//! - `btree_map`: Make it use BTreeMap instead of HashMap
10//! - `instruction_pos`: Add instruction position to bytecode for debugging
11//! - `serde_borsh`: Serde support for bytecode using Borsh
12
13mod instruction;
14#[macro_use]
15mod metadata;
16#[cfg(feature = "async")]
17mod channel;
18mod objects;
19#[macro_use]
20mod dispatcher;
21mod bytecode;
22mod ffi;
23mod stack;
24mod value;
25mod vm;
26
27pub mod gc;
28pub mod types {
29    pub use crate::value::*;
30}
31
32pub mod parser {
33    pub use go_parser::*;
34}
35
36pub use {
37    ffi::*,
38    go_parser::{Map, MapIter},
39    go_pmacro::{ffi_impl, Ffi, UnsafePtr},
40    value::Bytecode,
41    vm::run,
42    vm::PanicData,
43};
44
45pub struct CallStackDisplay<'a> {
46    panic_data: &'a PanicData,
47    bc: &'a Bytecode,
48}
49
50impl<'a> CallStackDisplay<'a> {
51    pub fn new(panic_data: &'a PanicData, bc: &'a Bytecode) -> CallStackDisplay<'a> {
52        Self { panic_data, bc }
53    }
54}
55
56impl<'a> std::fmt::Display for CallStackDisplay<'a> {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        for (fkey, pc) in self.panic_data.call_stack.iter() {
59            let func = &self.bc.objects.functions[*fkey];
60            if let Some(p) = func.pos[*pc as usize] {
61                if let Some(fs) = &self.bc.file_set {
62                    writeln!(
63                        f,
64                        "{}",
65                        fs.position(p as usize)
66                            .unwrap_or(go_parser::FilePos::null())
67                    )?;
68                } else {
69                    writeln!(f, "fileset not available, pos:{}", p)?;
70                }
71            } else {
72                f.write_str("<no debug info available for current frame>\n")?;
73            };
74        }
75        Ok(())
76    }
77}