Skip to content

Commit 2599633

Browse files
committed
VM: 新 debugger (未完成)
1 parent 6c65a4a commit 2599633

6 files changed

Lines changed: 210 additions & 3 deletions

File tree

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef OM_RUNTIME_ERROR_HPP
2+
#define OM_RUNTIME_ERROR_HPP
3+
4+
#include <exception>
5+
6+
namespace openminecraft::vm::err
7+
{
8+
class OMRuntimeError : public std::exception
9+
{
10+
private:
11+
void *errInstance;
12+
13+
public:
14+
OMRuntimeError(void *errInstance);
15+
virtual const char *what() const throw();
16+
};
17+
} // namespace openminecraft::vm::err
18+
19+
#endif

include/openminecraft/vm/pixeltower/om_pixeltower_classloader.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "openminecraft/vm/classfile/om_class_file.hpp"
66
#include "openminecraft/vm/pixeltower/om_pixeltower_class_structdef.hpp"
77
#include <any>
8-
#include <functional>
98
#include <list>
109
#include <memory>
1110

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef OM_PIXELTOWER_DEBUGGER_HPP
2+
#define OM_PIXELTOWER_DEBUGGER_HPP
3+
4+
#include "openminecraft/log/om_log_common.hpp"
5+
#include "openminecraft/vm/pixeltower/om_pixeltower_interpreter.hpp"
6+
#include <any>
7+
#include <memory>
8+
namespace openminecraft::vm::pixeltower::v1
9+
{
10+
class OMDebugger
11+
{
12+
public:
13+
OMDebugger(std::shared_ptr<runtime::OMInterpreter> interpreter);
14+
void printStack();
15+
16+
private:
17+
std::string serializeAny(std::any data, int objDepth = 0);
18+
19+
std::shared_ptr<runtime::OMInterpreter> interpreter;
20+
log::OMLogger logger;
21+
};
22+
} // namespace openminecraft::vm::pixeltower::v1
23+
24+
#endif

src/boot/entrypoint.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "openminecraft/vm/err/om_validation_error.hpp"
3434
#include "openminecraft/vm/pixeltower/om_pixeltower.hpp"
3535
#include "openminecraft/vm/pixeltower/om_pixeltower_array_structdef.hpp"
36+
#include "openminecraft/vm/pixeltower/om_pixeltower_debugger.hpp"
3637
#include "openminecraft/vm/pixeltower/om_pixeltower_interpreter.hpp"
3738
#include "openminecraft/vm/pixeltower/om_pixeltower_memorymanager.hpp"
3839
#include <SDL3/SDL.h>
@@ -115,6 +116,8 @@ int boot(std::vector<std::string> args)
115116
SDL_Quit();
116117

117118
auto pt = std::make_unique<OMPixelTower>();
119+
auto deb =
120+
std::make_unique<v1::OMDebugger>(std::any_cast<std::shared_ptr<runtime::OMInterpreter>>(pt->interpreter));
118121

119122
std::shared_ptr<OMClassFileParser> parser;
120123
bool recovermode = false;
@@ -175,6 +178,7 @@ int boot(std::vector<std::string> args)
175178
catch (vm::err::OMValidationError err)
176179
{
177180
logger->error(err.what());
181+
deb->printStack();
178182
}
179183

180184
commandBuffer.clear();
@@ -189,8 +193,9 @@ int boot(std::vector<std::string> args)
189193
}
190194

191195
auto cmdPrint = [&](std::any data) {
192-
logger->debug("[stdout] {}",
193-
pt->printAny(*(++std::any_cast<std::list<std::any> *>(data)->begin()), 0));
196+
/*logger->debug("[stdout] {}",
197+
pt->printAny(*(++std::any_cast<std::list<std::any> *>(data)->begin()), 0));*/
198+
logger->debug("[stdout] not implemented");
194199
return nullptr;
195200
};
196201

src/vm/err/om_runtime_error.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#include "openminecraft/vm/err/om_runtime_error.hpp"
2+
#include "fmt/format.h"
3+
4+
namespace openminecraft::vm::err
5+
{
6+
OMRuntimeError::OMRuntimeError(void *errInstance) : errInstance(errInstance)
7+
{
8+
}
9+
const char *OMRuntimeError::what() const throw()
10+
{
11+
auto i = new std::string(fmt::format("runtime error thrown with instance {}", errInstance));
12+
return i->c_str();
13+
}
14+
} // namespace openminecraft::vm::err
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
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

Comments
 (0)