2
0

Interpreter.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. #include "LuaDocumentElementInstancer.h"
  2. #include "LuaEventListenerInstancer.h"
  3. #include "LuaPlugin.h"
  4. #include <RmlUi/Core/Core.h>
  5. #include <RmlUi/Core/FileInterface.h>
  6. #include <RmlUi/Core/Log.h>
  7. #include <RmlUi/Lua/Interpreter.h>
  8. #include <RmlUi/Lua/LuaType.h>
  9. namespace Rml {
  10. namespace Lua {
  11. static int ErrorHandler(lua_State* L)
  12. {
  13. const char* msg = lua_tostring(L, 1);
  14. if (msg == NULL)
  15. {
  16. if (luaL_callmeta(L, 1, "__tostring") && lua_type(L, -1) == LUA_TSTRING)
  17. return 1;
  18. else
  19. msg = lua_pushfstring(L, "(error object is a %s value)", luaL_typename(L, 1));
  20. }
  21. luaL_traceback(L, L, msg, 1);
  22. return 1;
  23. }
  24. static bool LuaCall(lua_State* L, int nargs, int nresults)
  25. {
  26. int errfunc = -2 - nargs;
  27. lua_pushcfunction(L, ErrorHandler);
  28. lua_insert(L, errfunc);
  29. if (lua_pcall(L, nargs, nresults, errfunc) != LUA_OK)
  30. {
  31. Log::Message(Log::LT_WARNING, "%s", lua_tostring(L, -1));
  32. lua_pop(L, 2);
  33. return false;
  34. }
  35. lua_remove(L, -1 - nresults);
  36. return true;
  37. }
  38. lua_State* Interpreter::GetLuaState()
  39. {
  40. return LuaPlugin::GetLuaState();
  41. }
  42. bool Interpreter::LoadFile(const String& file)
  43. {
  44. lua_State* L = GetLuaState();
  45. // use the file interface to get the contents of the script
  46. FileInterface* file_interface = GetFileInterface();
  47. FileHandle handle = file_interface->Open(file);
  48. if (handle == 0)
  49. {
  50. Log::Message(Log::LT_WARNING, "LoadFile: Unable to open file: %s", file.c_str());
  51. return false;
  52. }
  53. size_t size = file_interface->Length(handle);
  54. if (size == 0)
  55. {
  56. Log::Message(Log::LT_WARNING, "LoadFile: File is 0 bytes in size: %s", file.c_str());
  57. return false;
  58. }
  59. UniquePtr<char[]> file_contents(new char[size]);
  60. file_interface->Read(file_contents.get(), size, handle);
  61. file_interface->Close(handle);
  62. if (luaL_loadbuffer(L, file_contents.get(), size, ("@" + file).c_str()) != 0)
  63. {
  64. Log::Message(Log::LT_WARNING, "%s", lua_tostring(L, -1));
  65. lua_pop(L, 1);
  66. return false;
  67. }
  68. return LuaCall(L, 0, 0);
  69. ;
  70. }
  71. bool Interpreter::DoString(const String& code, const String& name)
  72. {
  73. lua_State* L = GetLuaState();
  74. return LoadString(code, name) && LuaCall(L, 0, 0);
  75. }
  76. bool Interpreter::LoadString(const String& code, const String& name)
  77. {
  78. lua_State* L = GetLuaState();
  79. if (luaL_loadbuffer(L, code.c_str(), code.length(), name.c_str()) != 0)
  80. {
  81. Log::Message(Log::LT_WARNING, "%s", lua_tostring(L, -1));
  82. lua_pop(L, 1);
  83. return false;
  84. }
  85. return true;
  86. }
  87. void Interpreter::BeginCall(int funRef)
  88. {
  89. lua_State* L = GetLuaState();
  90. lua_settop(L, 0); // empty stack
  91. // lua_getref(g_L,funRef);
  92. lua_rawgeti(L, LUA_REGISTRYINDEX, (int)funRef);
  93. }
  94. bool Interpreter::ExecuteCall(int params, int res)
  95. {
  96. lua_State* L = GetLuaState();
  97. return LuaCall(L, params, res);
  98. }
  99. void Interpreter::EndCall(int res)
  100. {
  101. lua_State* L = GetLuaState();
  102. lua_pop(L, res);
  103. }
  104. } // namespace Lua
  105. } // namespace Rml