Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
hrydgard
GitHub Repository: hrydgard/ppsspp
Path: blob/master/Core/LuaContext.cpp
3185 views
1
#include <string>
2
3
#include "Common/Log.h"
4
#include "Common/StringUtils.h"
5
#include "Core/LuaContext.h"
6
#include "Core/MemMap.h"
7
8
// Sol is expensive to include so we only do it here.
9
#include "ext/sol/sol.hpp"
10
11
LuaContext g_lua;
12
13
static bool IsProbablyExpression(std::string_view input) {
14
// Heuristic: If it's a single-line statement without assignment or keywords, assume it's an expression.
15
return !(input.find("=") != std::string_view::npos ||
16
input.find("function") != std::string_view::npos ||
17
input.find("do") != std::string_view::npos ||
18
input.find("end") != std::string_view::npos ||
19
input.find("return") != std::string_view::npos ||
20
input.find("local") != std::string_view::npos);
21
}
22
23
// Custom print function
24
static void print(const std::string& message) {
25
g_lua.Print(message);
26
}
27
28
// TODO: Should these also echo to the console?
29
static void debug(const std::string &message) {
30
DEBUG_LOG(Log::System, "%s", message.c_str());
31
}
32
33
static void info(const std::string &message) {
34
INFO_LOG(Log::System, "%s", message.c_str());
35
}
36
37
static void warn(const std::string &message) {
38
WARN_LOG(Log::System, "%s", message.c_str());
39
}
40
41
static void error(const std::string &message) {
42
ERROR_LOG(Log::System, "%s", message.c_str());
43
}
44
45
// TODO: We should probably disallow or at least discourage raw read/writes and instead
46
// only support read/writes that refer to the name of a memory region.
47
static int r32(int address) {
48
if (Memory::IsValid4AlignedAddress(address)) {
49
return Memory::Read_U32(address);
50
} else {
51
g_lua.Print(LogLineType::Error, StringFromFormat("r32: bad address %08x", address));
52
return 0;
53
}
54
}
55
56
static void w32(int address, int value) {
57
if (Memory::IsValid4AlignedAddress(address)) {
58
Memory::Write_U32(value, address); // NOTE: These are backwards for historical reasons.
59
} else {
60
g_lua.Print(LogLineType::Error, StringFromFormat("w32: bad address %08x trying to write %08x", address, value));
61
}
62
}
63
64
void LuaContext::Init() {
65
_dbg_assert_(lua_ == nullptr);
66
lua_.reset(new sol::state());
67
lua_->open_libraries(sol::lib::base);
68
lua_->open_libraries(sol::lib::table);
69
lua_->open_libraries(sol::lib::bit32);
70
lua_->open_libraries(sol::lib::string);
71
lua_->open_libraries(sol::lib::math);
72
73
extern const char *PPSSPP_GIT_VERSION;
74
lua_->set("ver", PPSSPP_GIT_VERSION);
75
76
lua_->set("print", &print);
77
lua_->set("debug", &debug);
78
lua_->set("info", &info);
79
lua_->set("warn", &warn);
80
lua_->set("error", &error);
81
82
lua_->set("r32", &r32);
83
}
84
85
void LuaContext::Shutdown() {
86
lua_.reset();
87
}
88
89
const char *SolTypeToString(sol::type type) {
90
switch (type) {
91
case sol::type::boolean: return "boolean";
92
default: return "other";
93
}
94
}
95
96
void LuaContext::Print(LogLineType type, std::string_view text) {
97
lines_.push_back(LuaLogLine{ type, std::string(text)});
98
}
99
100
void LuaContext::ExecuteConsoleCommand(std::string_view cmd) {
101
// TODO: Also rewrite expressions like:
102
// print "hello"
103
// to
104
// print("hello") ?
105
try {
106
std::string command;
107
if (IsProbablyExpression(cmd)) {
108
command = "return ";
109
command += cmd;
110
} else {
111
command = cmd;
112
}
113
auto result = lua_->script(command);
114
if (result.valid()) {
115
for (const sol::stack_proxy &item : result) {
116
switch (item.get_type()) {
117
case sol::type::number:
118
{
119
int num = item.get<int>();
120
lines_.push_back(LuaLogLine{ LogLineType::Integer, StringFromFormat("%08x (%d)", num, num), item.get<int>()});
121
break;
122
}
123
case sol::type::string:
124
{
125
// TODO: Linebreak multi-line strings.
126
lines_.push_back(LuaLogLine{ LogLineType::String, item.get<std::string>() });
127
break;
128
}
129
default:
130
break;
131
}
132
}
133
} else {
134
sol::error err = result;
135
lines_.push_back(LuaLogLine{ LogLineType::Error, std::string(err.what()) });
136
}
137
} catch (const sol::error& e) {
138
ERROR_LOG(Log::System, "Lua exception: %s", e.what());
139
lines_.push_back(LuaLogLine{ LogLineType::Error, std::string(e.what()) });
140
}
141
}
142
143