不正コードの確認

守矢諏訪子 <suwako@076.moe>、2026-06-25 23:10
コミット 287da7d9cfe547329d72a4f7a7eea55e143e11ad ・親 dff300c ・ファイルを見る

4個のファイル、+157 -40

@@ -65,16 +65,28 @@
6565 LuaEngine(const string &code, Program *prog, gui::ConsoleLog *cmd = nullptr);
6666 ~LuaEngine();
6767
68+ public:
6869 LuaMesh &GetMesh() { return m_Mesh; };
6970 const LuaMesh &GetMesh() const { return m_Mesh; };
71+
72+ public:
7073 void Reload(const string &code);
7174 void Update();
75+ bool Validate(const string &code);
76+
77+ public:
7278 void SetProgram(Program *prog) { m_Program = prog; }
7379 void SetConsole(gui::ConsoleLog *cmd) { m_Console = cmd; }
80+ string GetApiVersion() const { return m_ApiVersion; }
7481
7582 private:
76- void BindGraphics();
77- void Execute();
83+ void LogError(sol::error err);
84+ void LogError(const std::exception &err);
85+ sol::state MakeAPI();
86+ void BindEngine(sol::state &lua);
87+ void BindSystem(sol::state &lua);
88+ void BindGraphics(sol::state &lua);
89+ void Execute(sol::state &lua);
7890
7991 private:
8092 LuaMesh m_Mesh;
@@ -82,5 +94,6 @@
8294 string m_Code;
8395 Program *m_Program = nullptr;
8496 gui::ConsoleLog *m_Console = nullptr;
97+ string m_ApiVersion = "1.0.0";
8598 };
8699 } // namespace lua
変更 main.cc
@@ -161,6 +161,23 @@
161161 LUA.code = luaEditor.Get().GetText();
162162
163163 try {
164+ try {
165+ if (!luaEngine.Validate(LUA.code)) {
166+ gui::LogEntry entry;
167+ entry.type = gui::LogType::Error;
168+ entry.text = "Luaコードが不正ですので、コンパイル出来ませんでした。";
169+ cmd.Add(entry);
170+ std::cout << entry.text << std::endl;
171+ return;
172+ }
173+ } catch (const std::exception &e) {
174+ gui::LogEntry entry;
175+ entry.type = gui::LogType::Error;
176+ entry.text = e.what();
177+ cmd.Add(entry);
178+ std::cout << entry.text << std::endl;
179+ }
180+
164181 shaderProgram.Reload(VERT.code, FRAG.code);
165182 luaEngine.SetProgram(&shaderProgram);
166183 luaEngine.Reload(LUA.code);
@@ -194,7 +211,11 @@
194211 }
195212 }
196213 } catch (const std::exception &e) {
197- std::cerr << e.what() << std::endl;
214+ gui::LogEntry entry;
215+ entry.type = gui::LogType::Error;
216+ entry.text = e.what();
217+ cmd.Add(entry);
218+ std::cerr << entry.text << std::endl;
198219 }
199220
200221 gui::LogEntry entry;
@@ -208,6 +229,23 @@
208229 VERT.code = vertEditor.Get().GetText();
209230 FRAG.code = fragEditor.Get().GetText();
210231 LUA.code = luaEditor.Get().GetText();
232+
233+ try {
234+ if (!luaEngine.Validate(LUA.code)) {
235+ gui::LogEntry entry;
236+ entry.type = gui::LogType::Error;
237+ entry.text = "Luaコードが不正ですので、保存出来ませんでした。";
238+ cmd.Add(entry);
239+ std::cout << entry.text << std::endl;
240+ return;
241+ }
242+ } catch (const std::exception &e) {
243+ gui::LogEntry entry;
244+ entry.type = gui::LogType::Error;
245+ entry.text = e.what();
246+ cmd.Add(entry);
247+ std::cout << entry.text << std::endl;
248+ }
211249
212250 db::SaveCode(db, VERT);
213251 db::SaveCode(db, FRAG);
@@ -44,23 +44,14 @@
4444 , m_Program(prog)
4545 , m_Console(cmd)
4646 {
47- m_Lua.open_libraries(
48- sol::lib::base,
49- sol::lib::math,
50- sol::lib::table,
51- sol::lib::string
52- );
53-
54- BindGraphics();
55- Execute();
47+ m_Lua = MakeAPI();
5648 }
5749
58- LuaEngine::~LuaEngine() {
59- }
50+ LuaEngine::~LuaEngine() {}
6051
6152 void LuaEngine::Reload(const string &code) {
6253 m_Code = code;
63- Execute();
54+ Execute(m_Lua);
6455 }
6556
6657 void LuaEngine::Update() {
@@ -70,19 +61,93 @@
7061
7162 if (!res.valid()) {
7263 sol::error err = res;
73- gui::LogEntry entry = {};
74- entry.type = gui::LogType::Error;
75- entry.text = err.what();
76- if (m_Console) m_Console->Add(entry);
77- else std::cerr << err.what() << std::endl;
64+ LogError(err);
7865 }
7966 }
8067 }
8168
82- void LuaEngine::BindGraphics() {
83- m_Lua["graphics"] = m_Lua.create_table();
69+ bool LuaEngine::Validate(const string &code) {
70+ try {
71+ sol::load_result resSyntax = m_Lua.load(code);
72+ if (!resSyntax.valid()) {
73+ sol::error err = resSyntax;
74+ LogError(err);
75+ return false;
76+ }
8477
85- m_Lua["graphics"]["set_mesh"] = [&](sol::table t) {
78+ sol::state testApi = MakeAPI();
79+ sol::protected_function_result resApi = testApi.safe_script(code);
80+ if (!resApi.valid()) {
81+ sol::error err = resApi;
82+ LogError(err);
83+ return false;
84+ }
85+
86+ return true;
87+ } catch (const sol::error &err) {
88+ LogError(err);
89+ return false;
90+ }
91+ }
92+
93+ ////////////////////
94+
95+ void LuaEngine::LogError(sol::error err) {
96+ gui::LogEntry entry = {};
97+ entry.type = gui::LogType::Error;
98+ entry.text = err.what();
99+ if (m_Console) m_Console->Add(entry);
100+ else std::cerr << err.what() << std::endl;
101+ }
102+
103+ void LuaEngine::LogError(const std::exception &err) {
104+ gui::LogEntry entry = {};
105+ entry.type = gui::LogType::Error;
106+ entry.text = err.what();
107+ if (m_Console) m_Console->Add(entry);
108+ else std::cerr << err.what() << std::endl;
109+ }
110+
111+ sol::state LuaEngine::MakeAPI() {
112+ sol::state out;
113+
114+ out.open_libraries(
115+ sol::lib::base,
116+ sol::lib::math,
117+ sol::lib::table,
118+ sol::lib::string
119+ );
120+
121+ try {
122+ BindEngine(out);
123+ BindSystem(out);
124+ BindGraphics(out);
125+ Execute(out);
126+ } catch (const std::exception &e) {
127+ LogError(e);
128+ return {};
129+ }
130+
131+ return out;
132+ }
133+
134+ void LuaEngine::BindEngine(sol::state &lua) {
135+ lua["le"] = lua.create_table();
136+ lua["le"]["api_version"] = m_ApiVersion;
137+ }
138+
139+ void LuaEngine::BindSystem(sol::state &lua) {
140+ lua["le"]["sys"] = lua.create_table();
141+
142+ lua["le"]["sys"]["get_time"] = [&]() -> f32 {
143+ return (f32)glfwGetTime();
144+ };
145+ }
146+
147+ void LuaEngine::BindGraphics(sol::state &lua) {
148+ lua["le"]["gfx"] = lua.create_table();
149+
150+ lua["le"]["gfx"]["set_mesh"] = [&](sol::table t) {
86151 m_Mesh.vertices.clear();
87152 m_Mesh.indices.clear();
88153 m_Mesh.attr.clear();
@@ -97,6 +162,15 @@
97162 for (auto &k : attrs) {
98163 sol::table a = k.second;
99164
165+ sol::optional<int> location = a["location"];
166+ sol::optional<int> size = a["size"];
167+ sol::optional<int> stride = a["stride"];
168+ sol::optional<int> offset = a["offset"];
169+
170+ if (!location || !size || !stride || !offset) {
171+ throw std::runtime_error("メッシュアトリビュートが不正です。");
172+ }
173+
100174 m_Mesh.attr.push_back({
101175 a["location"],
102176 a["size"],
@@ -106,26 +180,18 @@
106180 }
107181 };
108182
109- m_Lua["graphics"]["get_time"] = [&]() -> f32 {
110- return (f32)glfwGetTime();
111- };
112-
113- m_Lua["graphics"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) {
183+ lua["le"]["gfx"]["set_uniform3"] = [&](const string &name, f32 x, f32 y, f32 z) {
114184 if (!m_Program) return;
115185 glUniform3f(m_Program->GetUniformLocation(name), x, y, z);
116186 };
117187 }
118188
119- void LuaEngine::Execute() {
120- sol::protected_function_result res = m_Lua.safe_script(m_Code);
189+ void LuaEngine::Execute(sol::state &lua) {
190+ sol::protected_function_result res = lua.safe_script(m_Code);
121191
122192 if (!res.valid()) {
123193 sol::error err = res;
124- gui::LogEntry entry = {};
125- entry.type = gui::LogType::Error;
126- entry.text = err.what();
127- if (m_Console) m_Console->Add(entry);
128- else std::cerr << err.what() << std::endl;
194+ LogError(err);
129195 }
130196 }
131197 } // namespace lua
@@ -150,28 +150,28 @@
150150 }
151151 }
152152
153-graphics.set_mesh(mesh)
153+le.gfx.set_mesh(mesh)
154154
155155 function update()
156- local t = graphics.get_time() -- glfwGetTime()
156+ local t = le.sys.get_time() -- glfwGetTime()
157157 local speed = 1.0 -- animation speed
158158 local phase = math.pi * 2.0 / 3.0 -- 120 deg phase diff (3 color)
159159
160- graphics.set_uniform3(
160+ le.gfx.set_uniform3(
161161 "uColorA",
162162 math.sin(t * speed + 0.0) * 0.5 + 0.5,
163163 math.sin(t * speed + phase) * 0.5 + 0.5,
164164 math.sin(t * speed + phase * 2.0) * 0.5 + 0.5
165165 )
166166
167- graphics.set_uniform3(
167+ le.gfx.set_uniform3(
168168 "uColorB",
169169 math.sin(t * speed + phase * 2.0) * 0.5 + 0.5,
170170 math.sin(t * speed + 0.0) * 0.5 + 0.5,
171171 math.sin(t * speed + phase) * 0.5 + 0.5
172172 )
173173
174- graphics.set_uniform3(
174+ le.gfx.set_uniform3(
175175 "uColorC",
176176 math.sin(t * speed + phase) * 0.5 + 0.5,
177177 math.sin(t * speed + phase * 2.0) * 0.5 + 0.5,