1+ #include " openminecraft/vm/pixeltower/om_pixeltower_debugger.hpp"
2+ #include " fmt/color.h"
3+ #include " openminecraft/i18n/om_i18n_res.hpp"
4+ #include " openminecraft/log/om_log_threadname.hpp"
5+ #include " openminecraft/vm/classfile/om_class_file.hpp"
6+ #include " openminecraft/vm/pixeltower/om_pixeltower_array_structdef.hpp"
7+ #include " openminecraft/vm/pixeltower/om_pixeltower_class_structdef.hpp"
8+ #include " openminecraft/vm/pixeltower/om_pixeltower_frame_structdef.hpp"
9+ #include " openminecraft/vm/pixeltower/om_pixeltower_interpreter.hpp"
10+ #include < any>
11+ #include < memory>
12+ #include < sstream>
13+ #include < stack>
14+ #include < typeindex>
15+
16+ namespace openminecraft ::vm::pixeltower
17+ {
18+ extern std::string ARRAY_TYPE ;
19+ }
20+
21+ namespace openminecraft ::vm::pixeltower::v1
22+ {
23+ OMDebugger::OMDebugger (std::shared_ptr<runtime::OMInterpreter> i)
24+ : interpreter(i), logger(" pixeltower/OMDebugger" , this )
25+ {
26+ }
27+ void OMDebugger::printStack ()
28+ {
29+ for (auto stackItem : interpreter->stack )
30+ {
31+ std::stack<std::any> cpy (stackItem.second );
32+
33+ logger.debug (" Stack status for thread: {}" , log::multithread::acquireThreadName (stackItem.first ));
34+ int i = 0 ;
35+ while (!cpy.empty ())
36+ {
37+ auto text = fmt::format (" * {} {}" , fmt::styled (fmt::format (" [{}]" , i), fmt::fg (fmt::color::light_blue)),
38+ serializeAny (cpy.top ()));
39+
40+ std::istringstream s (text);
41+ std::string line;
42+ while (std::getline (s, line, ' \n ' ))
43+ {
44+ logger.debug (line);
45+ }
46+ cpy.pop ();
47+ i++;
48+ }
49+ }
50+ }
51+ std::string OMDebugger::serializeAny (std::any data, int objDepth)
52+ {
53+ auto prefix = std::string (objDepth * 4 , ' ' );
54+
55+ auto idx = std::type_index (data.type ());
56+ if (idx == std::type_index (typeid (int )))
57+ {
58+ return fmt::format (" {}{}" , prefix, fmt::styled (std::any_cast<int >(data), fmt::fg (fmt::color::light_green)));
59+ }
60+ else if (idx == std::type_index (typeid (float )))
61+ {
62+ return fmt::format (" {}{}" , prefix, fmt::styled (std::any_cast<float >(data), fmt::fg (fmt::color::light_green)));
63+ }
64+ else if (idx == std::type_index (typeid (double )))
65+ {
66+ return fmt::format (" {}{}" , prefix, fmt::styled (std::any_cast<double >(data), fmt::fg (fmt::color::light_green)));
67+ }
68+ else if (idx == std::type_index (typeid (int64_t )))
69+ {
70+ return fmt::format (" {}{}" , prefix, fmt::styled (std::any_cast<int64_t >(data), fmt::fg (fmt::color::light_green)));
71+ }
72+ else if (idx == std::type_index (typeid (std::shared_ptr<runtime::OMFrameMetadata>)))
73+ {
74+ auto frameMd = std::any_cast<std::shared_ptr<runtime::OMFrameMetadata>>(data);
75+ auto cls = std::string (frameMd->clazz ->name .c_str ());
76+ for (int i = 0 ; i < cls.size (); i++)
77+ {
78+ if (cls[i] == ' /' )
79+ {
80+ cls[i] = ' .' ;
81+ }
82+ }
83+ auto base = fmt::format (" {}Frame base for {}.{}{}" , prefix, fmt::styled (cls, fmt::fg (fmt::color::cyan)),
84+ fmt::styled (frameMd->method ->name , fmt::fg (fmt::color::purple)),
85+ fmt::styled (frameMd->method ->desc , fmt::fg (fmt::color::gray)));
86+
87+ objDepth++;
88+ prefix = std::string (objDepth * 4 , ' ' );
89+
90+ base += " \n " + prefix + " Next bytecodes: \n " + prefix;
91+ for (uint64_t i = 0 ; i < 8 ; i++)
92+ {
93+ bool inRange = frameMd->codeLength > (i + frameMd->offset );
94+ base += fmt::format (" {:#04x} " , fmt::styled (frameMd->codePointer [i + frameMd->offset ],
95+ fmt::fg (inRange ? fmt::color::yellow : fmt::color::gray)));
96+ }
97+ base += " \n " + prefix + " Locals:" ;
98+ int i = 0 ;
99+ for (auto local : frameMd->local )
100+ {
101+ base += fmt::format (" \n {}- {}\n {}" , prefix,
102+ fmt::styled (fmt::format (" [{}]" , i), fmt::fg (fmt::color::light_blue)),
103+ serializeAny (local, objDepth + 1 ));
104+ i++;
105+ }
106+ return base;
107+ }
108+ else if (idx == std::type_index (typeid (void *)))
109+ {
110+ auto baseptr = std::any_cast<void *>(data);
111+ auto arrh = (OMArrayHeader *)baseptr;
112+
113+ if (baseptr == nullptr )
114+ {
115+ return fmt::format (" {}{}" , prefix, fmt::styled (" null" , fmt::fg (fmt::color::gray)));
116+ }
117+ if (arrh->classifierPointer == &ARRAY_TYPE )
118+ {
119+ return fmt::format (" {}{}" , prefix, fmt::styled (" <array>" , fmt::fg (fmt::color::gray)));
120+ }
121+
122+ auto cls = *((OMClass **)baseptr);
123+ auto target =
124+ fmt::format (" {}instance at {} with type {}" , prefix, fmt::styled (baseptr, fmt::fg (fmt::color::red)),
125+ fmt::styled (cls->name , fmt::fg (fmt::color::light_green)));
126+ for (auto fi : cls->fields )
127+ {
128+ if ((fi->accessFlag & JVM_Acc_Static) == 0 )
129+ {
130+ target += fmt::format (" \n {}field {}" , prefix, fmt::styled (fi->name , fmt::fg (fmt::color::light_green)));
131+ }
132+ }
133+ return target;
134+ }
135+ else if (idx == std::type_index (typeid (void )))
136+ {
137+ return fmt::format (" {}{}" , prefix, fmt::styled (" nothing" , fmt::fg (fmt::color::gray)));
138+ }
139+ else
140+ {
141+ return fmt::format (
142+ " {}{}" , prefix,
143+ fmt::styled (fmt::format (" unknown data with descriptor {}" , data.type ().name ()), fmt::fg (fmt::color::gray)));
144+ }
145+ }
146+ } // namespace openminecraft::vm::pixeltower::v1
0 commit comments