From e4f77870d2e2282754a28643dda4e6efb69ca114 Mon Sep 17 00:00:00 2001 From: Topaz Whitelock Date: Wed, 16 Feb 2022 18:35:15 +0300 Subject: [PATCH] First push. --- .gitattributes | 2 + .gitignore | 4 + AboutFrontend.cpp | 14 + AboutFrontend.hpp | 22 + AboutFrontend.ui | 180 + AboutPatreon.cpp | 14 + AboutPatreon.hpp | 22 + AboutPatreon.ui | 107 + Console.cpp | 36 + Console.hpp | 22 + Console.ui | 54 + DOCUMENT.md | 180 + LuaBackend.cpp | 237 + LuaBackend.hpp | 59 + LuaFrontend.pro | 57 + LuaThread.cpp | 54 + LuaThread.hpp | 33 + Main.cpp | 14 + MainWindow.cpp | 992 + MainWindow.hpp | 115 + MainWindow.ui | 259 + README.md | 80 +- Resources.qrc | 9 + WaitDialog.cpp | 29 + WaitDialog.hpp | 25 + WaitDialog.ui | 57 + Windows.rc | 31 + configs/gameConfig.toml | 47 + configs/prefConfig.toml | 6 + include/DCInstance.hpp | 52 + include/MemoryLib.hpp | 283 + include/Operator32Lib.hpp | 28 + include/crcpp/CRC32.h | 2054 ++ include/discord/discord_register.h | 26 + include/discord/discord_rpc.h | 87 + include/lua/lapi.h | 49 + include/lua/lauxlib.h | 293 + include/lua/lcode.h | 104 + include/lua/lctype.h | 101 + include/lua/ldebug.h | 63 + include/lua/ldo.h | 79 + include/lua/lfunc.h | 64 + include/lua/lgc.h | 189 + include/lua/ljumptab.h | 112 + include/lua/llex.h | 91 + include/lua/llimits.h | 353 + include/lua/lmem.h | 93 + include/lua/lobject.h | 800 + include/lua/lopcodes.h | 392 + include/lua/lopnames.h | 103 + include/lua/lparser.h | 171 + include/lua/lprefix.h | 45 + include/lua/lstate.h | 404 + include/lua/lstring.h | 57 + include/lua/ltable.h | 66 + include/lua/ltm.h | 103 + include/lua/lua.h | 518 + include/lua/lua.hpp | 9 + include/lua/luaconf.h | 790 + include/lua/lualib.h | 52 + include/lua/lundump.h | 36 + include/lua/lvm.h | 136 + include/lua/lzio.h | 66 + include/sol2/config.hpp | 53 + include/sol2/forward.hpp | 828 + include/sol2/sol.hpp | 26710 ++++++++++++++++++++++ include/toml11/toml.hpp | 46 + include/toml11/toml/color.hpp | 64 + include/toml11/toml/combinator.hpp | 306 + include/toml11/toml/comments.hpp | 472 + include/toml11/toml/datetime.hpp | 631 + include/toml11/toml/exception.hpp | 65 + include/toml11/toml/from.hpp | 19 + include/toml11/toml/get.hpp | 1117 + include/toml11/toml/into.hpp | 19 + include/toml11/toml/lexer.hpp | 270 + include/toml11/toml/literal.hpp | 112 + include/toml11/toml/macros.hpp | 121 + include/toml11/toml/parser.hpp | 2179 ++ include/toml11/toml/region.hpp | 417 + include/toml11/toml/result.hpp | 717 + include/toml11/toml/serializer.hpp | 853 + include/toml11/toml/source_location.hpp | 233 + include/toml11/toml/storage.hpp | 43 + include/toml11/toml/string.hpp | 224 + include/toml11/toml/traits.hpp | 325 + include/toml11/toml/types.hpp | 173 + include/toml11/toml/utility.hpp | 149 + include/toml11/toml/value.hpp | 2035 ++ languages/en_US.ts | 372 + languages/tr_TR.ts | 401 + libraries/discord-rpc.lib | Bin 0 -> 3622 bytes libraries/lua.lib | Bin 0 -> 29950 bytes resources/error.png | Bin 0 -> 1183 bytes resources/good.png | Bin 0 -> 960 bytes resources/iconMain.ico | Bin 0 -> 122684 bytes resources/iconMain.png | Bin 0 -> 23166 bytes resources/iconPatreon.png | Bin 0 -> 10667 bytes resources/warning.png | Bin 0 -> 832 bytes version.h | 21 + 100 files changed, 49604 insertions(+), 1 deletion(-) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 AboutFrontend.cpp create mode 100644 AboutFrontend.hpp create mode 100644 AboutFrontend.ui create mode 100644 AboutPatreon.cpp create mode 100644 AboutPatreon.hpp create mode 100644 AboutPatreon.ui create mode 100644 Console.cpp create mode 100644 Console.hpp create mode 100644 Console.ui create mode 100644 DOCUMENT.md create mode 100644 LuaBackend.cpp create mode 100644 LuaBackend.hpp create mode 100644 LuaFrontend.pro create mode 100644 LuaThread.cpp create mode 100644 LuaThread.hpp create mode 100644 Main.cpp create mode 100644 MainWindow.cpp create mode 100644 MainWindow.hpp create mode 100644 MainWindow.ui create mode 100644 Resources.qrc create mode 100644 WaitDialog.cpp create mode 100644 WaitDialog.hpp create mode 100644 WaitDialog.ui create mode 100644 Windows.rc create mode 100644 configs/gameConfig.toml create mode 100644 configs/prefConfig.toml create mode 100644 include/DCInstance.hpp create mode 100644 include/MemoryLib.hpp create mode 100644 include/Operator32Lib.hpp create mode 100644 include/crcpp/CRC32.h create mode 100644 include/discord/discord_register.h create mode 100644 include/discord/discord_rpc.h create mode 100644 include/lua/lapi.h create mode 100644 include/lua/lauxlib.h create mode 100644 include/lua/lcode.h create mode 100644 include/lua/lctype.h create mode 100644 include/lua/ldebug.h create mode 100644 include/lua/ldo.h create mode 100644 include/lua/lfunc.h create mode 100644 include/lua/lgc.h create mode 100644 include/lua/ljumptab.h create mode 100644 include/lua/llex.h create mode 100644 include/lua/llimits.h create mode 100644 include/lua/lmem.h create mode 100644 include/lua/lobject.h create mode 100644 include/lua/lopcodes.h create mode 100644 include/lua/lopnames.h create mode 100644 include/lua/lparser.h create mode 100644 include/lua/lprefix.h create mode 100644 include/lua/lstate.h create mode 100644 include/lua/lstring.h create mode 100644 include/lua/ltable.h create mode 100644 include/lua/ltm.h create mode 100644 include/lua/lua.h create mode 100644 include/lua/lua.hpp create mode 100644 include/lua/luaconf.h create mode 100644 include/lua/lualib.h create mode 100644 include/lua/lundump.h create mode 100644 include/lua/lvm.h create mode 100644 include/lua/lzio.h create mode 100644 include/sol2/config.hpp create mode 100644 include/sol2/forward.hpp create mode 100644 include/sol2/sol.hpp create mode 100644 include/toml11/toml.hpp create mode 100644 include/toml11/toml/color.hpp create mode 100644 include/toml11/toml/combinator.hpp create mode 100644 include/toml11/toml/comments.hpp create mode 100644 include/toml11/toml/datetime.hpp create mode 100644 include/toml11/toml/exception.hpp create mode 100644 include/toml11/toml/from.hpp create mode 100644 include/toml11/toml/get.hpp create mode 100644 include/toml11/toml/into.hpp create mode 100644 include/toml11/toml/lexer.hpp create mode 100644 include/toml11/toml/literal.hpp create mode 100644 include/toml11/toml/macros.hpp create mode 100644 include/toml11/toml/parser.hpp create mode 100644 include/toml11/toml/region.hpp create mode 100644 include/toml11/toml/result.hpp create mode 100644 include/toml11/toml/serializer.hpp create mode 100644 include/toml11/toml/source_location.hpp create mode 100644 include/toml11/toml/storage.hpp create mode 100644 include/toml11/toml/string.hpp create mode 100644 include/toml11/toml/traits.hpp create mode 100644 include/toml11/toml/types.hpp create mode 100644 include/toml11/toml/utility.hpp create mode 100644 include/toml11/toml/value.hpp create mode 100644 languages/en_US.ts create mode 100644 languages/tr_TR.ts create mode 100644 libraries/discord-rpc.lib create mode 100644 libraries/lua.lib create mode 100644 resources/error.png create mode 100644 resources/good.png create mode 100644 resources/iconMain.ico create mode 100644 resources/iconMain.png create mode 100644 resources/iconPatreon.png create mode 100644 resources/warning.png create mode 100644 version.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1bc641b --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ + +libraries/discord-rpc.dll +libraries/Lua.dll +LuaFrontend.pro.user diff --git a/AboutFrontend.cpp b/AboutFrontend.cpp new file mode 100644 index 0000000..6687b36 --- /dev/null +++ b/AboutFrontend.cpp @@ -0,0 +1,14 @@ +#include "AboutFrontend.hpp" +#include "ui_AboutFrontend.h" + +AboutFrontend::AboutFrontend(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutFrontend) +{ + ui->setupUi(this); +} + +AboutFrontend::~AboutFrontend() +{ + delete ui; +} diff --git a/AboutFrontend.hpp b/AboutFrontend.hpp new file mode 100644 index 0000000..9150459 --- /dev/null +++ b/AboutFrontend.hpp @@ -0,0 +1,22 @@ +#ifndef ABOUTFRONTEND_HPP +#define ABOUTFRONTEND_HPP + +#include + +namespace Ui { +class AboutFrontend; +} + +class AboutFrontend : public QDialog +{ + Q_OBJECT + +public: + explicit AboutFrontend(QWidget *parent = nullptr); + ~AboutFrontend(); + +private: + Ui::AboutFrontend *ui; +}; + +#endif // ABOUTFRONTEND_HPP diff --git a/AboutFrontend.ui b/AboutFrontend.ui new file mode 100644 index 0000000..6cd5b4d --- /dev/null +++ b/AboutFrontend.ui @@ -0,0 +1,180 @@ + + + AboutFrontend + + + Qt::WindowModal + + + + 0 + 0 + 633 + 188 + + + + About LuaFrontend + + + + :/resources/iconMain.ico:/resources/iconMain.ico + + + + + 14 + 8 + 171 + 171 + + + + + + + :/resources/iconMain.png + + + true + + + + + + 200 + 3 + 291 + 41 + + + + + 14 + true + + + + LuaFrontend v1.15 + + + + + + 200 + 60 + 411 + 21 + + + + + 10 + false + + + + LuaFrontend powered by Qt 6.2.2 (MSVC 2019, x64) + + + + + + 200 + 33 + 311 + 21 + + + + + 10 + false + + + + Compatible with LuaEngine v5.10. + + + + + + 200 + 105 + 411 + 21 + + + + + 9 + false + + + + Copyright 2020-2022 / TopazTK - Certain rights reserved. + + + + + + 200 + 125 + 411 + 21 + + + + + 9 + false + + + + Copyright 2008-2022 / Qt Company Ltd. All rights reserved. + + + + + + 200 + 153 + 421 + 21 + + + + + 9 + false + + + + 3rd Party libraries included. See the Github Repository for info. + + + + + + 200 + 78 + 411 + 21 + + + + + 10 + false + + + + LuaEngine powered by Lua 5.4.3 (MSVC 2019, x64) + + + + + + + + diff --git a/AboutPatreon.cpp b/AboutPatreon.cpp new file mode 100644 index 0000000..126d0d0 --- /dev/null +++ b/AboutPatreon.cpp @@ -0,0 +1,14 @@ +#include "AboutPatreon.hpp" +#include "ui_AboutPatreon.h" + +AboutPatreon::AboutPatreon(QWidget *parent) : + QDialog(parent), + ui(new Ui::AboutPatreon) +{ + ui->setupUi(this); +} + +AboutPatreon::~AboutPatreon() +{ + delete ui; +} diff --git a/AboutPatreon.hpp b/AboutPatreon.hpp new file mode 100644 index 0000000..6632570 --- /dev/null +++ b/AboutPatreon.hpp @@ -0,0 +1,22 @@ +#ifndef ABOUTPATREON_HPP +#define ABOUTPATREON_HPP + +#include + +namespace Ui { +class AboutPatreon; +} + +class AboutPatreon : public QDialog +{ + Q_OBJECT + +public: + explicit AboutPatreon(QWidget *parent = nullptr); + ~AboutPatreon(); + +private: + Ui::AboutPatreon *ui; +}; + +#endif // ABOUTPATREON_HPP diff --git a/AboutPatreon.ui b/AboutPatreon.ui new file mode 100644 index 0000000..30bdfcf --- /dev/null +++ b/AboutPatreon.ui @@ -0,0 +1,107 @@ + + + AboutPatreon + + + Qt::WindowModal + + + + 0 + 0 + 633 + 188 + + + + Consider... + + + + :/resources/iconMain.ico:/resources/iconMain.ico + + + + + 14 + 8 + 171 + 171 + + + + + + + :/resources/iconPatreon.png + + + true + + + + + + 200 + 3 + 291 + 41 + + + + + 14 + true + + + + Consider Supporting TopazTK! + + + + + + 200 + 45 + 411 + 101 + + + + + 9 + false + + + + <html><head/><body><p>TopazTK is a lone developer, trying his best to make programs like LuaFrontend, and mods like Re:Fixed possible. Unfortunately, however, he is not financially stable enough to pour a lot of time to these projects. By supporting TopazTK on Patreon, you can make it possible for him to work on these things for longer, allowing him to do his passion job! There are also some benefits to this so please, do consider.</p></body></html> + + + true + + + + + + 200 + 153 + 421 + 21 + + + + + 9 + false + + + + <html><head/><body><p>Any support is appreciated: <a href="https://patreon.com/topaztk"><span style=" text-decoration: underline; color:#007af4;">https://patreon.com/topaztk</span></a></p></body></html> + + + + + + + + diff --git a/Console.cpp b/Console.cpp new file mode 100644 index 0000000..a455d82 --- /dev/null +++ b/Console.cpp @@ -0,0 +1,36 @@ +#include +#include + +Console::Console(QWidget *parent) : QDialog(parent), ui(new Ui::Console) +{ + ui->setupUi(this); + + ui->output->setStyleSheet("font: 9pt \"Consolas\";"); + + ui->output->append("========================================"); + ui->output->append("== LuaFrontend v1.15S - Powered by QT =="); + ui->output->append("======= Copyright 2021 - TopazTK ======="); + ui->output->append("========================================"); + ui->output->append("==== Compatible with LuaEngine v5.1 ===="); + ui->output->append("========================================"); + ui->output->append(""); + + connect(this, SIGNAL(rejected()), parent, SLOT(consoleToggle())); +} + +Console::~Console() +{ + delete ui; +} + +void Console::printMessage(QString inputTxt, int type) +{ + QString _colors[] = { "CADETBLUE", "GREEN", "ORANGE", "RED" }; + QString _titles[] = { "MESSAGE", "SUCCESS", "WARNING", "ERROR" }; + + QString _prefix = "%2: "; + _prefix = _prefix.arg(_colors[type], _titles[type]); + + inputTxt = inputTxt.replace("\n", "
"); + ui->output->append(_prefix + inputTxt); +} diff --git a/Console.hpp b/Console.hpp new file mode 100644 index 0000000..331bd0d --- /dev/null +++ b/Console.hpp @@ -0,0 +1,22 @@ +#ifndef CONSOLE_H +#define CONSOLE_H + +#include + +namespace Ui { class Console; } + +class Console : public QDialog +{ + Q_OBJECT + + public: + void printMessage(QString, int type = 0); + + explicit Console(QWidget *parent = nullptr); + ~Console(); + + private: + Ui::Console *ui; +}; + +#endif // CONSOLE_H diff --git a/Console.ui b/Console.ui new file mode 100644 index 0000000..1b0b1b6 --- /dev/null +++ b/Console.ui @@ -0,0 +1,54 @@ + + + Console + + + + 0 + 0 + 438 + 354 + + + + LuaEngine Console [v5.0 | STABLE] + + + + :/resources/iconMain.ico:/resources/iconMain.ico + + + + 0 + + + 5 + + + 5 + + + 5 + + + 5 + + + + + <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> +<html><head><meta name="qrichtext" content="1" /><meta charset="utf-8" /><style type="text/css"> +p, li { white-space: pre-wrap; } +</style></head><body style=" font-family:'Segoe UI'; font-size:9pt; font-weight:400; font-style:normal;"> +<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'MS Shell Dlg 2'; font-size:8.25pt;"><br /></p></body></html> + + + false + + + + + + + + diff --git a/DOCUMENT.md b/DOCUMENT.md new file mode 100644 index 0000000..3333db1 --- /dev/null +++ b/DOCUMENT.md @@ -0,0 +1,180 @@ +## LuaEngine Cheatsheet v5.10 + +--- + +## Global Variables + +- ``GAME_ID`` => Returns the current game's CRC32 checksum as an integer. This checksum is generated from the process name at this moment. +- ``LUA_NAME`` => The name of your Lua script, used by functions such as ConsolePrint. It is the filename of your Lua by default. +- ``SCRIPT_PATH`` => Returns the path which Lua scripts are loaded from as a string. Ex: ``"C:\Users\Topaz\Desktop\LuaBackend\scripts"`` +- ``CHEATS_PATH`` => Always returns ``"NOT_AVAILABLE"`` +- ``ENGINE_VERSION`` => Returns the LuaBackend's engine version as a float. Ex: ``5`` +- ``ENGINE_TYPE`` => Always returns ``"BACKEND"`` + +## Memory Functions + +### Read\[XXXX\](Address, Absolute = false) / ReadString(Address, Length, Absolute = false) + +Reads a certain value from **Address**. Returns the read value. If reading a String, length must also be declared. +The "**XXXX**" is a placeholder for the value type. + +If **Absolute** is true, the address is taken as written and base address is not added into it. + +List of types available: Byte, Short, Int, Long, Float, String, Boolean + +Example: +```lua + local _tempInt = ReadInt(0xDEADB00) -- Read an integer from address BaseAddress+0xDEADB00 + local _tempByte = ReadByte(0xB007555) -- Read a byte from address BaseAddress+0xB007555 +``` + +### Write\[XXXX\](Address, Value, Abolsute = false) + +Writes **Value** to **Address** calculated relative to the base address. +The "**\[XXXX\]**" is a placeholder for the value type. + +If **Absolute** is true, the address is taken as written and base address is not added into it. + +List of types available: Byte, Short, Int, Long, Float, String, Boolean + +Example: +```lua + WriteShort(0xDEADB00, 0xFFFF) -- Write 0xFFFF to BaseAddress+0xDEADB00 + WriteBoolean(0xB007555, true) -- Write true to BaseAddress+0xB007555 +``` + + +### ReadArray(Address, Length, Absolute = false) + +Reads **Length** amount of bytes from memory, starting at **Address**. Returns the read bytes as an array. +If **Absolute** is true, the address is taken as written and base address is not added into it. + +Example: +```lua + local _tempArray = ReadArray(0xBEEFDED, 0x10) -- Reads 16 bytes starting at BaseAddress+0xBEEFDED +``` + +### WriteArray(Address, Array, Absolute = false) + +Writes **Array** to the memory, starting at **Address**. The array must be made of bytes (8-bit integers). +If **Absolute** is true, the address is taken as written and base address is not added into it. + +Example: +```lua + local _tempArray = { 0xFE, 0xA5, 0x70 } + WriteArray(0x6660420, _tempArray) -- Writes _tempArray to memory, starting at BaseAddress+0x6660420 +``` + +### GetPointer(Address, Offset, Absolute = false) + +Calculates a pointer with the given values. +Basically, reads the value at **Address** and adds **Offset** to it. Returns the resulting value. + +If **Absolute** is true, the address is taken as written and base address is not added into it. + +Example: +```lua + local _tempPointer = GetPointer(0xBEEFDAD, 0x15) -- Reads the value at BaseAddress+0xBEEFDAD and adds 0x15 to it. +``` + +## General I/O Functions + +### GetHertz() + +Gets the frequency of which LuaBackend scripts execute. + +### SetHertz(Frequency) + +Sets the Backend execution cycle to **Frequency**. The accepted values are **60**, **120**, and **240**. + +### ULShift32(Base, Shift) + +Shifts **Base** left by **Shift** abont of bytes. Only exists for 32-bit applications. + +Example: +```lua + ULShift32(4294967295, 8) -- Shifts 4294967295 left by 8 bytes without an overflow to 64-bits. +``` + +### ConsolePrint(Text, Type = NULL) + +Prints **Text** to the console, in the format given below. +Unless **Type** is declared, nothing will prefix the message. + +**Type** can be the following: +- 0 = MESSAGE +- 1 = SUCCESS +- 2 = WARNING +- 3 = ERROR + +Format: +``` +[LUA_NAME] TYPE: Text +``` + +Example: +```lua + LUA_NAME = "SomeDudeScript" + ConsolePrint("GET UP ON THE HYDRA'S BACK!") -- Prints the following: [SomeDudeScript] GET UP ON THE HYDRA'S BACK! + ConsolePrint("NICE VIEW FROM UP HERE!", 0) -- Prints the following: [SomeDudeScript] MESSAGE: NICE VIEW FROM UP HERE! +``` + +## Discord RPC Functions + +### InitializeRPC(ApplicationID) + +Initializes and hooks a Discord Application with **ApplicationID**, for Rich Presence control. + +Example: +```lua + InitializeRPC("833511404274974740") -- Initiaizes Discord Application "833511404274974740". +``` + +### UpdateDetails(Text) + +Updates the details of the rich presence application initialized with InitializeRPC to say **Text**. + +Example: +```lua + UpdateDetails("Hello World!") -- Updates the details section of the RPC to say "Hello World!". +``` + +### UpdateState(Text) + +Updates the state of the rich presence application initialized with InitializeRPC to say **Text**. + +Example: +```lua + UpdateState("Hello World!") -- Updates the state section of the RPC to say "Hello World!". +``` + +### UpdateLImage(Key, Text) + +Updates the large image of the rich presence to be the image with **Key**. And it's text is updates to say **Text**. + +Example: +```lua + UpdateLImage("image", "This is Image!") -- Updates the large image to "image" and it's text to "This is Image!" +``` + +### UpdateSImage(Key, Text) + +Updates the small image of the rich presence to be the image with **Key**. And it's text is updates to say **Text**. + +Example: +```lua + UpdateSImage("imagetwo", "This too, is Image!") -- Updates the small image to "imagetwo" and it's text to "This too, is Image!" +``` + +### WriteExec(Address, Value) + +Writes the given byte array **Value** to **Address** relative to the current EXE's address, NOT the provided base address. +This function is non-existent on PCSX2-EX. + +Example: +```lua + WriteExec(0x00FBAAD, 0x15) -- Writes 0x15 to EXE_NAME.exe+0x00FBAAD. + +``` + +#### * Any functions present in this document signify compatibility with the latest version. Any function absent in this document is no longer supported and should be considered obsolete. diff --git a/LuaBackend.cpp b/LuaBackend.cpp new file mode 100644 index 0000000..e365125 --- /dev/null +++ b/LuaBackend.cpp @@ -0,0 +1,237 @@ +#include + +LuaBackend::LuaBackend() { } + +LuaBackend::LuaBackend(const char* ScrPath, uint64_t BaseInput, Console* TargetConsole) +{ + frameLimit = 1000 / 60; + loadedScripts = vector(); + scrPath = ScrPath; + + _outputConsole = TargetConsole; + + LoadScripts(ScrPath, BaseInput); +} + +void LuaBackend::LoadScripts(const char* ScrPath, uint64_t BaseInput) +{ + loadedScripts.clear(); + auto _iterator = QDirIterator(ScrPath, QDirIterator::Subdirectories); + + while (_iterator.hasNext()) + { + auto _path = _iterator.next(); + + if (_path.contains(".lua") && !_path.contains("io_packages") && !_path.contains("io_load")) + { + LuaScript* _script = new LuaScript(); + + _script->scriptPath = _path; + + _script->luaState.open_libraries + ( + lib::base, + lib::package, + lib::coroutine, + lib::string, + lib::os, + lib::math, + lib::table, + lib::io, + lib::bit32, + lib::utf8 + ); + + _script->luaState.set_exception_handler(&ExceptionHandle); + + SetFunctions(&_script->luaState); + + string _luaPath = ScrPath; + _luaPath.append("\\io_packages\\?.lua"); + + string _dllPath = ScrPath; + _dllPath.append("\\io_packages\\?.dll"); + + _script->luaState["package"]["path"] = _luaPath; + _script->luaState["package"]["cpath"] = _dllPath; + + string _loadPath = ScrPath; + _loadPath.append("\\io_load"); + + _script->luaState["LOAD_PATH"] = _loadPath; + _script->luaState["SCRIPT_PATH"] = ScrPath; + _script->luaState["CHEATS_PATH"] = "NOT_AVAILABLE"; + + string _pathFull = MemoryLib::PName; + auto _pathExe = _pathFull.substr(_pathFull.find_last_of("\\") + 1); + + _script->luaState["ENGINE_VERSION"] = 5; + _script->luaState["ENGINE_TYPE"] = "BACKEND"; + _script->luaState["GAME_ID"] = CRC::Calculate(_pathExe.c_str(), _pathExe.length(), CRC::CRC_32()); + _script->luaState["BASE_ADDR"] = BaseInput; + + _script->parseResult = _script->luaState.script_file(_path.toStdString(), &sol::script_pass_on_error); + + _script->initFunction = _script->luaState["_OnInit"]; + _script->frameFunction = _script->luaState["_OnFrame"]; + + string _luaName = _path.split('/').last().toStdString(); + _script->luaState["LUA_NAME"] = _luaName.substr(0, _luaName.size() - 4); + + loadedScripts.push_back(_script); + } + } +} + +void LuaBackend::SetFunctions(LuaState* _state) +{ + // Reader Functions + + _state->set_function("ReadByte", + sol::overload + ( + [](uint64_t _addr) { return MemoryLib::ReadByte(_addr); }, + [](uint64_t _addr, bool _absolute) { return MemoryLib::ReadByte(_addr, _absolute); } + )); + + _state->set_function("ReadShort", + sol::overload + ( + [](uint64_t _addr) { return MemoryLib::ReadShort(_addr); }, + [](uint64_t _addr, bool _absolute) { return MemoryLib::ReadShort(_addr, _absolute); } + )); + + _state->set_function("ReadInt", + sol::overload + ( + [](uint64_t _addr) { return MemoryLib::ReadInt(_addr); }, + [](uint64_t _addr, bool _absolute) { return MemoryLib::ReadInt(_addr, _absolute); } + )); + + _state->set_function("ReadLong", + sol::overload + ( + [](uint64_t _addr) { return MemoryLib::ReadLong(_addr); }, + [](uint64_t _addr, bool _absolute) { return MemoryLib::ReadLong(_addr, _absolute); } + )); + + _state->set_function("ReadFloat", + sol::overload + ( + [](uint64_t _addr) { return MemoryLib::ReadFloat(_addr); }, + [](uint64_t _addr, bool _absolute) { return MemoryLib::ReadFloat(_addr, _absolute); } + )); + + _state->set_function("ReadBoolean", + sol::overload + ( + [](uint64_t _addr) { return MemoryLib::ReadBool(_addr); }, + [](uint64_t _addr, bool _absolute) { return MemoryLib::ReadBool(_addr, _absolute); } + )); + + _state->set_function("ReadArray", + sol::overload + ( + [](uint64_t _addr, int _len) { return MemoryLib::ReadBytes(_addr, _len); }, + [](uint64_t _addr, int _len, bool _absolute) { return MemoryLib::ReadBytes(_addr, _len, _absolute); } + )); + + _state->set_function("ReadString", + sol::overload + ( + [](uint64_t _addr, int _len) { return MemoryLib::ReadString(_addr, _len); }, + [](uint64_t _addr, int _len, bool _absolute) { return MemoryLib::ReadString(_addr, _len, _absolute); } + )); + + // Writer Functions + + _state->set_function("WriteByte", + sol::overload + ( + [](uint64_t _addr, uint8_t _val) { MemoryLib::WriteByte(_addr, _val); }, + [](uint64_t _addr, uint8_t _val, bool _absolute) { MemoryLib::WriteByte(_addr, _val, _absolute); } + )); + + _state->set_function("WriteShort", + sol::overload + ( + [](uint64_t _addr, uint16_t _val) { MemoryLib::WriteShort(_addr, _val); }, + [](uint64_t _addr, uint16_t _val, bool _absolute) { MemoryLib::WriteShort(_addr, _val, _absolute); } + )); + + _state->set_function("WriteInt", + sol::overload + ( + [](uint64_t _addr, uint32_t _val) { MemoryLib::WriteInt(_addr, _val); }, + [](uint64_t _addr, uint32_t _val, bool _absolute) { MemoryLib::WriteInt(_addr, _val, _absolute); } + )); + + _state->set_function("WriteLong", + sol::overload + ( + [](uint64_t _addr, uint64_t _val) { MemoryLib::WriteLong(_addr, _val); }, + [](uint64_t _addr, uint64_t _val, bool _absolute) { MemoryLib::WriteLong(_addr, _val, _absolute); } + )); + + _state->set_function("WriteFloat", + sol::overload + ( + [](uint64_t _addr, float _val) { MemoryLib::WriteFloat(_addr, _val); }, + [](uint64_t _addr, float _val, bool _absolute) { MemoryLib::WriteFloat(_addr, _val, _absolute); } + )); + + _state->set_function("WriteBoolean", + sol::overload + ( + [](uint64_t _addr, bool _val) { MemoryLib::WriteBool(_addr, _val); }, + [](uint64_t _addr, bool _val, bool _absolute) { MemoryLib::WriteBool(_addr, _val, _absolute); } + )); + + _state->set_function("WriteArray", + sol::overload + ( + [](uint64_t _addr, vector _val) { MemoryLib::WriteBytes(_addr, _val); }, + [](uint64_t _addr, vector _val, bool _absolute) { MemoryLib::WriteBytes(_addr, _val, _absolute); } + + )); + + _state->set_function("WriteString", + sol::overload + ( + [](uint64_t _addr, string _val) { MemoryLib::WriteString(_addr, _val); }, + [](uint64_t _addr, string _val, bool _absolute) { MemoryLib::WriteString(_addr, _val, _absolute); } + )); + + _state->set_function("WriteExec", MemoryLib::WriteExec); + + // Misc. Functions + + _state->set_function("ConsolePrint", + sol::overload( + [this](LuaObject Text) + { + auto _text = QString::fromStdString(Text.as()); + _outputConsole->printMessage(_text, 0); + }, + + [this](LuaObject Text, int MessageType) + { + auto _text = QString::fromStdString(Text.as()); + _outputConsole->printMessage(_text, MessageType); + } + ) + ); + + _state->set_function("GetHertz", [this]() { return floor(1000 / frameLimit); }); + _state->set_function("SetHertz", [this](int _input) { frameLimit = floor(1000 / _input); }); + + _state->set_function("ULShift32", Operator32Lib::UnsignedShift32); + + // Discord Functions + + _state->set_function("InitializeRPC", DCInstance::InitializeRPC); + _state->set_function("UpdateDetails", DCInstance::UpdateDetails); + _state->set_function("UpdateState", DCInstance::UpdateState); + _state->set_function("UpdateLImage", DCInstance::UpdateLImage); + _state->set_function("UpdateSImage", DCInstance::UpdateSImage); +} diff --git a/LuaBackend.hpp b/LuaBackend.hpp new file mode 100644 index 0000000..7c787ef --- /dev/null +++ b/LuaBackend.hpp @@ -0,0 +1,59 @@ +#ifndef LUABACKEND +#define LUABACKEND + +#include +#include + +#include +#include + +#include +#include +#include + +#include + +using namespace sol; +using namespace std; + +using LuaError = sol::error; +using LuaState = sol::state; +using LuaObject = sol::object; +using LuaFunction = sol::safe_function; +using LuaResult = sol::protected_function_result; + +class LuaBackend +{ + public: + struct LuaScript + { + LuaState luaState; + LuaResult parseResult; + LuaFunction initFunction; + LuaFunction frameFunction; + + QString scriptPath; + }; + + float frameLimit; + string scrPath; + + std::vector loadedScripts; + + static int ExceptionHandle(lua_State* luaState, sol::optional thrownException, sol::string_view) + { + const std::exception _ex = *thrownException; + return sol::stack::push(luaState, _ex.what()); + } + + void SetFunctions(LuaState*); + void LoadScripts(const char*, uint64_t); + + LuaBackend(); + LuaBackend(const char*, uint64_t, Console*); + + private: + Console* _outputConsole; +}; + +#endif diff --git a/LuaFrontend.pro b/LuaFrontend.pro new file mode 100644 index 0000000..a4cca08 --- /dev/null +++ b/LuaFrontend.pro @@ -0,0 +1,57 @@ +QT += core gui widgets network + +CONFIG += c++17 + +LIBS += -L$$PWD/libraries/ -llua -ldiscord-rpc +PRE_TARGETDEPS += $$PWD/libraries/discord-rpc.lib + +RC_ICONS = resources/iconMain.ico +RC_FILE = Windows.rc + +TRANSLATIONS = languages/tr_TR.ts languages/en_US.ts + + +SOURCES += \ + AboutFrontend.cpp \ + AboutPatreon.cpp \ + LuaThread.cpp \ + Main.cpp \ + Console.cpp \ + LuaBackend.cpp \ + MainWindow.cpp \ + WaitDialog.cpp \ + +HEADERS += \ + AboutFrontend.hpp \ + AboutPatreon.hpp \ + Console.hpp \ + LuaThread.hpp \ + WaitDialog.hpp \ + LuaBackend.hpp \ + MainWindow.hpp \ + version.h + +FORMS += \ + AboutFrontend.ui \ + AboutPatreon.ui \ + Console.ui \ + MainWindow.ui \ + WaitDialog.ui + +INCLUDEPATH += \ + $$PWD/include/ \ + $$PWD/include/lua \ + $$PWD/include/sol2 \ + $$PWD/include/crcpp \ + $$PWD/include/toml11 \ + $$PWD/include/discord + +DEPENDPATH += \ + $$PWD/include/lua \ + $$PWD/include/discord + +RESOURCES += \ + Resources.qrc + +DISTFILES += \ + Windows.rc diff --git a/LuaThread.cpp b/LuaThread.cpp new file mode 100644 index 0000000..41a7220 --- /dev/null +++ b/LuaThread.cpp @@ -0,0 +1,54 @@ +#include "LuaThread.hpp" + +LuaThread::LuaThread(Console* consoleInput) +{ + _thread = new QThread(this); + _runTimer = new QTimer(this); + + _console = consoleInput; +} + +void LuaThread::start() +{ + this->moveToThread(_thread); + + _runTimer->moveToThread(_thread); + + connect(_thread, SIGNAL(started()), this, SLOT(startEvent())); + connect(_runTimer, SIGNAL(timeout()), this, SLOT(runEvent())); + + _thread->start(); +} + +void LuaThread::stop() +{ + _runTimer->stop(); + _thread->exit(); +} + +void LuaThread::startEvent() +{ + _runTimer->start(runInterval); +} + +void LuaThread::runEvent() +{ + if (exeScript->frameFunction) + { + auto _result = exeScript->frameFunction(); + + if (!_result.valid()) + { + sol::error _err = _result; + + auto _errStr = QString(_err.what()); + _console->printMessage(_errStr + "
", 3); + + _runTimer->stop(); + _thread->exit(); + } + } + + if (_runTimer->interval() != runInterval) + _runTimer->setInterval(runInterval); +} diff --git a/LuaThread.hpp b/LuaThread.hpp new file mode 100644 index 0000000..c3aa17f --- /dev/null +++ b/LuaThread.hpp @@ -0,0 +1,33 @@ +#ifndef LUATHREAD_H +#define LUATHREAD_H + +#include +#include + +#include +#include + +class LuaThread : public QObject +{ + Q_OBJECT + public: + int runInterval; + LuaBackend::LuaScript* exeScript; + + LuaThread(Console*); + + void start(); + void stop(); + + private: + Console* _console; + + QThread* _thread; + QTimer* _runTimer; + + private slots: + void startEvent(); + void runEvent(); +}; + +#endif // LUATHREAD_H diff --git a/Main.cpp b/Main.cpp new file mode 100644 index 0000000..bc32a68 --- /dev/null +++ b/Main.cpp @@ -0,0 +1,14 @@ +#include "MainWindow.hpp" + +#include + +int main(int argc, char *argv[]) +{ + QApplication App(argc, argv); + App.setStyle("Fusion"); + + MainWindow w; + w.show(); + + return App.exec(); +} diff --git a/MainWindow.cpp b/MainWindow.cpp new file mode 100644 index 0000000..84dc946 --- /dev/null +++ b/MainWindow.cpp @@ -0,0 +1,992 @@ +#include +#include + +MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) +{ + + // VARIABLE INITIALIZATION + + _autoBool = false; + _threadBool = false; + _darkPalBool = false; + _consoleBool = false; + + _language = "en_US"; + + _basePath = QCoreApplication::applicationDirPath(); + + // FETCH LANGUAGE + + auto _tomlDir = QString(_basePath + "\\configs\\prefConfig.toml"); + toml::value _prefToml; + + try + { + _prefToml = toml::parse(_tomlDir.toStdString()); + + auto _tblStr = QString("Preferences"); + _prefTable = toml::find(_prefToml, _tblStr.toStdString()); + + auto _languageTemp = toml::find(_prefTable, "language").as_string(); + + if (!_languageTemp.str.empty()) + _language = QString::fromStdString(_languageTemp.str); + } + + catch (std::runtime_error _ex) { + + QMessageBox _warnBox; + + _warnBox.setMinimumWidth(256); + _warnBox.setIcon(QMessageBox::Warning); + _warnBox.setStandardButtons(QMessageBox::Ok); + + _warnBox.setDetailedText(_ex.what()); + _warnBox.setWindowTitle(tr("Error #403 - Cannot access file.")); + + _warnBox.setText(tr("The file \"prefConfig.toml\" cannot be found or accessed.\n" + "Default preferences will be loaded!")); + + _warnBox.exec(); + } + + + // TRANSLATE THE APP + + qApp->removeTranslator(&_translator); + + QString _baseLang = QApplication::applicationDirPath(); + _baseLang.append("/languages/"); + + if(_translator.load(_baseLang + _language)) + qApp->installTranslator(&_translator); + + // UI INITIALIZATION + + ui->setupUi(this); + + QStringList _labelList = { tr("Title"), tr("Author(s)"), tr("Description") }; + ui->scriptWidget->setHeaderLabels(_labelList); + ui->scriptWidget->setColumnWidth(0, 128); + + _aboutDiag = new AboutFrontend(this); + _patreonDiag = new AboutPatreon(this); + + _console = new Console(this); + _waitWindow = new WaitDialog(this); + + _runTimer = new QTimer(this); + latchTimer = new QTimer(this); + + _runTimer->moveToThread(this->thread()); + latchTimer->moveToThread(this->thread()); + + // SIGNAL CONSTRUCTOR + + connect(_runTimer, SIGNAL(timeout()), this, SLOT(runEvent())); + connect(latchTimer, SIGNAL(timeout()), this, SLOT(latchEvent())); + + connect(ui->actionDark, SIGNAL(triggered()), this, SLOT(darkToggle())); + connect(ui->actionAutoReload, SIGNAL(triggered()), this, SLOT(autoToggle())); + connect(ui->actionConsole, SIGNAL(triggered()), this, SLOT(consoleToggle())); + connect(ui->actionThreading, SIGNAL(triggered()), this, SLOT(threadToggle())); + + connect(ui->actionStop, SIGNAL(triggered()), this, SLOT(stopEvent())); + connect(ui->actionStart, SIGNAL(triggered()), this, SLOT(startEvent())); + connect(ui->actionReload, SIGNAL(triggered()), this, SLOT(reloadEvent())); + + connect(ui->gameWidget, SIGNAL(currentRowChanged(int)), this, SLOT(gameClickEvent(int))); + connect(ui->scriptWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)), this, SLOT(scriptClickEvent(QTreeWidgetItem*,int))); + + QAction *aboutAction = ui->mainMenu->addAction(tr("About")); + connect(aboutAction, SIGNAL(triggered()), this, SLOT(showAbout())); + + QAction *patreonAction = ui->mainMenu->addAction(tr("Patreon")); + connect(patreonAction, SIGNAL(triggered()), this, SLOT(showPatreon())); + + + connect(ui->en_US, SIGNAL(triggered()), this, SLOT(languageEvent())); + connect(ui->tr_TR, SIGNAL(triggered()), this, SLOT(languageEvent())); + + + // CONTEXT MENU CONSTRUCTOR + + connect(ui->gameWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(gameContextEvent(QPoint))); + connect(ui->scriptWidget, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(scriptContextEvent(QPoint))); + + // PALETTE INITIALIZATION + + _darkPal.setColor(QPalette::Window, QColor(53,53,53)); + _darkPal.setColor(QPalette::WindowText, Qt::white); + _darkPal.setColor(QPalette::Base, QColor(42,42,42)); + _darkPal.setColor(QPalette::AlternateBase, QColor(66,66,66)); + _darkPal.setColor(QPalette::ToolTipBase, Qt::white); + _darkPal.setColor(QPalette::ToolTipText, Qt::white); + _darkPal.setColor(QPalette::Text, Qt::white); + _darkPal.setColor(QPalette::Dark, QColor(35,35,35)); + _darkPal.setColor(QPalette::Shadow, QColor(20,20,20)); + _darkPal.setColor(QPalette::Button, QColor(53,53,53)); + _darkPal.setColor(QPalette::ButtonText, Qt::white); + _darkPal.setColor(QPalette::BrightText, Qt::red); + _darkPal.setColor(QPalette::Link, QColor(42,130,218)); + _darkPal.setColor(QPalette::Highlight, QColor(42,130,218)); + _darkPal.setColor(QPalette::HighlightedText, Qt::white); + _darkPal.setColor(QPalette::Disabled, QPalette::Text, QColor(127, 127, 127)); + _darkPal.setColor(QPalette::Disabled, QPalette::Highlight, QColor(80,80,80)); + _darkPal.setColor(QPalette::Disabled, QPalette::WindowText, QColor(127,127,127)); + _darkPal.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(127,127,127)); + _darkPal.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(127,127,127)); + + _lightPal = this->style()->standardPalette(); + + // FETCH SETTINGS + + try + { + _prefToml = toml::parse(_tomlDir.toStdString()); + + auto _tblStr = QString("Preferences"); + _prefTable = toml::find(_prefToml, _tblStr.toStdString()); + + auto _autoTemp = toml::find(_prefTable, "autoBool").as_boolean(); + auto _threadTemp = toml::find(_prefTable, "threadBool").as_boolean(); + auto _darkPalTemp = toml::find(_prefTable, "darkPalBool").as_boolean(); + auto _consoleTemp = toml::find(_prefTable, "consoleBool").as_boolean(); + auto _languageTemp = toml::find(_prefTable, "language").as_string(); + + if (_autoTemp) + autoToggle(); + + if (_threadTemp) + threadToggle(); + + if (_darkPalTemp) + darkToggle(); + + if (_consoleTemp) + consoleToggle(); + + if (!_languageTemp.str.empty()) + _language = QString::fromStdString(_languageTemp.str); + } + + catch (std::runtime_error _ex) { + + QMessageBox _warnBox; + + _warnBox.setMinimumWidth(256); + _warnBox.setIcon(QMessageBox::Warning); + _warnBox.setStandardButtons(QMessageBox::Ok); + + _warnBox.setDetailedText(_ex.what()); + _warnBox.setWindowTitle(tr("Error #403 - Cannot access file.")); + + _warnBox.setText(tr("The file \"prefConfig.toml\" cannot be found or accessed.\n" + "Default preferences will be loaded!")); + + _warnBox.exec(); + } + + // EXECUTION + + parseGame(); + parseScript(); +} + +MainWindow::~MainWindow() { delete ui; } + +// GENERAL FUNCTIONS + +int MainWindow::parseGame() +{ + // Spawn the error box. + // And also set all the variables commonly used. + + QMessageBox _errorBox; + + _errorBox.setMinimumWidth(256); + _errorBox.setIcon(QMessageBox::Critical); + _errorBox.setStandardButtons(QMessageBox::Ok); + + // Fetch the game configuation database. + + auto _tomlDir = QString(_basePath + "\\configs\\gameConfig.toml"); + + // Try to read it. If the file cannot be accessed for... whatever, + // act accordingly and cancel the operations. + + try { _gameToml = toml::parse(_tomlDir.toStdString()); } + catch (std::runtime_error _ex) { + + _errorBox.setDetailedText(_ex.what()); + _errorBox.setWindowTitle(tr("Error #403 - Cannot access file.")); + + _errorBox.setText(tr("The file \"gameConfig.toml\" cannot be found or accessed.\n" + "Game Configuration could not be loaded!\n" + "LuaFrontend will now be terminated.")); + + _errorBox.exec(); + + exit(403); + } + + // Go through all of the elements and parse them. + // Make the first index as the current table, and + // select it in the box. + + for (std::size_t i = 0; i < _gameToml.size(); i++) + { + auto _tblStr = QString("GameEntry%1").arg(i, 2, 10, QLatin1Char('0')); + auto _table = toml::find(_gameToml, _tblStr.toStdString()); + + if (i == 0) + { + auto _tmpOffset = QString::fromStdString(toml::find(_table, "Offset").as_string().str); + auto _tmpAddress = QString::fromStdString(toml::find(_table, "Address").as_string().str); + + _currGame.exeName = QString::fromStdString(toml::find(_table, "Executable").as_string().str); + _currGame.gameName = QString::fromStdString(toml::find(_table, "Title").as_string().str); + _currGame.scriptPath = QString::fromStdString(toml::find(_table, "Path").as_string().str); + + _currGame.isBigEndian = toml::find(_table, "BigEndian").as_boolean(); + + _currGame.offset = _tmpOffset.toULong(nullptr, 16); + _currGame.baseAddress = _tmpAddress.toULong(nullptr, 16); + } + + auto _name = toml::find(_table, "Title").as_string().str; + auto _nameStr = QString::fromStdString(_name); + + ui->gameWidget->addItem(_nameStr); + ui->gameWidget->setCurrentRow(0); + } + + return 0; +} + +int MainWindow::parseScript() +{ + // Clear the script widget first. + + ui->scriptWidget->clear(); + + // Figure out what path we are working with. + // Is it absolute or relative? If it has a slash + // as it's first character, it's relative to us. + + auto _path = _currGame.scriptPath; + + if (_path.at(0) == '/' || _path.at(0) == '\\') + _path = _basePath + _path; + + // Check if the script folder actually + // exists. If it does not, error out. + + QDir _scriptDir(_path); + auto _existBool = _scriptDir.exists(); + + if (!_existBool) + return 404; + + // Feed the information to a fake backend. + // This backend runs nothing. It's just there + // to check the scripts. + + backendFake = new LuaBackend(_path.toStdString().c_str(), 0x00000000, _console); + + // Fun. Do the below for every script: + + for (size_t i = 0; i < backendFake->loadedScripts.size(); i++) + { + // Make a tree item for them. Regardless if + // they are valid or not, we are adding 'em in. + + auto _item = new QTreeWidgetItem(); + auto _script = backendFake->loadedScripts[i]; + + // Make the tree item have the default + // values for the script. + + string _luaName = _script->luaState["LUA_NAME"]; + + _item->setData(0, 1392, QVariant(0)); + _item->setData(0, 1807, QVariant(_script->scriptPath)); + + _item->setText(0, QString::fromStdString(_luaName)); + _item->setText(1, tr("Unknown")); + _item->setText(2, tr("Not Available.")); + + // If the script is valid, do the following: + + if (_script->parseResult.valid()) + { + // We check if either the init or the frame + // function is absent. If so, this script will + // throw a warning stating as such. But it will + // still be runnable. + + auto _initCheck = _script->initFunction; + auto _frameCheck = _script->frameFunction; + + if ((!_initCheck || !_frameCheck) && (!_initCheck && !_frameCheck) == false) + { + QString _message = ""; + + if (!_initCheck) + _message = tr("Warning #1: Initialization function cannot be found or is invalid."); + + if (!_frameCheck) + _message = tr("Warning #2: Frame function cannot be found or is invalid."); + + // Has a warning? Uncheck it. + + _item->setIcon(0, QIcon(":/resources/warning.png")); + _item->setCheckState(0, Qt::CheckState::Unchecked); + _item->setToolTip(0, _message); + } + + else if (!_initCheck && !_frameCheck) + { + _item->setIcon(0, QIcon(":/resources/error.png")); + _item->setToolTip(0, tr("Error #199: Not a valid LuaBackend script.\n" + "Cannot be executed.")); + } + + else + { + // All OK scripts are checked off by default. + + _item->setCheckState(0, Qt::CheckState::Checked); + _item->setIcon(0, QIcon(":/resources/good.png")); + } + } + + // If the script is invalid, state as such and + // make it non-checkable. + + else + { + LuaError _err = _script->parseResult; + + _item->setData(0, 1392, QVariant(_err.what())); + _item->setIcon(0, QIcon(":/resources/error.png")); + _item->setToolTip(0, tr("Error #200: Not a valid Lua script.\n" + "Fatal errors were encountered.")); + } + + // Try and parse the LUAGUI elements. + // Verify if they exist, and if they do, + // use them in the GUI. + + LuaObject _nameScr = _script->luaState["LUAGUI_NAME"]; + LuaObject _authScr = _script->luaState["LUAGUI_AUTH"]; + LuaObject _descScr = _script->luaState["LUAGUI_DESC"]; + + if (_nameScr.valid() && _nameScr.as().length() > 0) + _item->setText(0, QString::fromStdString(_nameScr.as())); + + if (_authScr.valid() && _authScr.as().length() > 0) + _item->setText(1, QString::fromStdString(_authScr.as())); + + if (_descScr.valid() && _descScr.as().length() > 0) + _item->setText(2, QString::fromStdString(_descScr.as())); + + // Add the dang item. + + ui->scriptWidget->addTopLevelItem(_item); + } + + return 0; +} + +// TOGGLE EVENTS + +void MainWindow::darkToggle() +{ + QString _titleTxt = tr("Switch to %1 Mode"); + + _darkPalBool ? qApp->setPalette(_lightPal) : qApp->setPalette(_darkPal); + _darkPalBool ? _titleTxt = _titleTxt.arg(tr("Dark")) : _titleTxt = _titleTxt.arg(tr("Light")); + + ui->actionDark->setText(_titleTxt); + + _darkPalBool = !_darkPalBool; + _prefTable["darkPalBool"] = _darkPalBool; + + serializePref(); +} + +void MainWindow::autoToggle() +{ + QString _titleTxt = tr("%1 Auto-Reload"); + + _autoBool ? _titleTxt = _titleTxt.arg(tr("Enable")) : _titleTxt = _titleTxt.arg(tr("Disable")); + ui->actionAutoReload->setText(_titleTxt); + + _autoBool = !_autoBool; + _prefTable["autoBool"] = _autoBool; + + serializePref(); +} + +void MainWindow::consoleToggle() +{ + QString _titleTxt = tr("%1 Console..."); + + _consoleBool ? _console->hide() : _console->show(); + _consoleBool ? _titleTxt = _titleTxt.arg(tr("Show")) : _titleTxt = _titleTxt.arg(tr("Hide")); + + ui->actionConsole->setText(_titleTxt); + + _consoleBool = !_consoleBool; + _prefTable["consoleBool"] = _consoleBool; + + serializePref(); +} + +void MainWindow::threadToggle() +{ + bool _threadAccept = _threadBool; + + if (!_threadBool && ui->mainWidget->isVisible()) + { + QMessageBox _warnBox; + + _warnBox.setMinimumWidth(256); + _warnBox.setIcon(QMessageBox::Warning); + _warnBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + + _warnBox.setWindowTitle(tr("A lil' note about Thread-per-Script.")); + + _warnBox.setText(tr("This option enables the Thread-per-Script functionality.\n" + "This functionality is currently in Beta and requires as many threads as\n" + "there are scripts. Are you sure you want to enable it?")); + + if (_warnBox.exec() == QMessageBox::Yes) + _threadAccept = true; + } + + if (_threadAccept || !ui->mainWidget->isVisible()) + { + QString _titleTxt = tr("%1 Multi-Threading"); + + _threadBool ? _titleTxt = _titleTxt.arg(tr("Enable")) : _titleTxt = _titleTxt.arg(tr("Disable")); + ui->actionThreading->setText(_titleTxt); + + _threadBool = !_threadBool; + _prefTable["threadBool"] = _threadBool; + + serializePref(); + } +} + +// TRIGGER EVENTS + +void MainWindow::startEvent() +{ + // Activate the timer which will + // take care of everything necessary. + + _waitWindow->show(); + latchTimer->start(100); +} + +void MainWindow::stopEvent() +{ + // Reset the console. + + _console->close(); + _console = new Console(this); + + // Stop the run thread. + + _runTimer->stop(); + + if (_threadBool) + for (auto _thread : _threadList) + _thread->stop(); + + _threadList.clear(); + + // Restore the buttons. + + ui->actionStart->setEnabled(true); + ui->actionReload->setEnabled(false); + ui->actionStop->setEnabled(false); +} + +void MainWindow::reloadEvent() +{ + // Reset the console. + + _console->close(); + _console = new Console(this); + + // Stop the run thread... or threads. + + _runTimer->stop(); + + if (_threadBool) + for (auto _thread : _threadList) + _thread->stop(); + + _threadList.clear(); + + // Run the latch thread with the window. + + _waitWindow->show(); + latchTimer->start(); + + // Restore the buttons + // Just in case the reload fails. + + ui->actionStart->setEnabled(true); + ui->actionReload->setEnabled(false); + ui->actionStop->setEnabled(false); +} + +void MainWindow::gameClickEvent(int currentRow) +{ + auto _tblStr = QString("GameEntry%1").arg(currentRow, 2, 10, QLatin1Char('0')); + auto _table = toml::find(_gameToml, _tblStr.toStdString()); + + auto _tmpOffset = QString::fromStdString(toml::find(_table, "Offset").as_string().str); + auto _tmpAddress = QString::fromStdString(toml::find(_table, "Address").as_string().str); + + _currGame.exeName = QString::fromStdString(toml::find(_table, "Executable").as_string().str); + _currGame.gameName = QString::fromStdString(toml::find(_table, "Title").as_string().str); + _currGame.scriptPath = QString::fromStdString(toml::find(_table, "Path").as_string().str); + + _currGame.isBigEndian = toml::find(_table, "BigEndian").as_boolean(); + + _currGame.offset = _tmpOffset.toULong(nullptr, 16); + _currGame.baseAddress = _tmpAddress.toULong(nullptr, 16); + + if (parseScript() == 404) + { + QMessageBox _errorBox; + + _errorBox.setMinimumWidth(512); + _errorBox.setIcon(QMessageBox::Critical); + _errorBox.setStandardButtons(QMessageBox::Ok); + + _errorBox.setWindowTitle(tr("Error #404: Folder not found!")); + _errorBox.setText(tr("The script folder for this game does not exist.\n" + "Please edit the game information or create the folder.")); + + _errorBox.exec(); + } +} + +void MainWindow::scriptClickEvent(QTreeWidgetItem *item, int) +{ + // Capture the data. + + auto _errData = item->data(0, 1392); + + // If the data is non-existent, + // do absolutely nothing. + + if (_errData.toString() == "0") + return; + + // If there IS data, bind the data + // do the following; + + else + { + // Construct the box. + + QMessageBox _errorBox; + + _errorBox.setMinimumWidth(512); + _errorBox.setIcon(QMessageBox::Critical); + _errorBox.setStandardButtons(QMessageBox::Ok); + + // This is only for Error #200. Set the + // title and the text accordingly. + + _errorBox.setWindowTitle(tr("Error #200: Invalid Script")); + _errorBox.setText(tr("This script is not a valid Lua script.\n" + "Fatal errors were encountered.")); + + // Set the detailed text to the error + // given out by sol3, then execute the + // box. + + _errorBox.setDetailedText(_errData.toString()); + _errorBox.exec(); + } +} + +// OFF-TRIGGER EVENTS + +void MainWindow::connectEvent() +{ + // Calculate the path as we do in + // parseScript(). + + auto _path = _currGame.scriptPath; + + if (_path.at(0) == '/' || _path.at(0) == '\\') + _path = _basePath + _path; + + // Calculate the base address that we + // need to feed into the backend. + + auto _baseAddress = _currGame.baseAddress; + auto _exeAddress = (uint64_t)MemoryLib::FindBaseAddr(MemoryLib::PHandle, _currGame.exeName.toStdString()); + + // If we want the base address of the Executable, + // calculate accordingly. Otherwise, add the offset + // to the given address. + + if (_baseAddress == 0) + _baseAddress = _exeAddress + _currGame.offset; + + else + _baseAddress += _currGame.offset; + + MemoryLib::SetBaseAddr(_baseAddress); + + // Feed the information to a read backend. + // This backend actually runs everything needed. + + backend = new LuaBackend(_path.toStdString().c_str(), _baseAddress, _console); + + // Since there is a two-way sorting, this is easy. + // Check the state of the script widget. Make a new + // script list with the ticked scripts. + + vector _scriptList; + + for (int i = 0; i < ui->scriptWidget->topLevelItemCount(); i++) + { + auto _item = ui->scriptWidget->topLevelItem(i); + + if (_item->checkState(0) == Qt::CheckState::Checked) + _scriptList.push_back(backend->loadedScripts[i]); + } + + // Feed the newly made list to the backend. + + backend->loadedScripts.clear(); + backend->loadedScripts = _scriptList; + + // Execute the initialization functions. + + for (auto _script : backend->loadedScripts) + { + if (_script->initFunction) + { + auto _result = _script->initFunction(); + + if (!_result.valid()) + { + sol::error _err = _result; + + auto _errStr = QString(_err.what()); + _console->printMessage(_errStr + "
", 3); + } + } + } + + // Set the buttons, show the console, + // and run the main loop thread. + + ui->actionStart->setEnabled(false); + ui->actionReload->setEnabled(true); + ui->actionStop->setEnabled(true); + + if (!_consoleBool) + consoleToggle(); + + _runTimer->start(backend->frameLimit); + + if (_threadBool) + { + _threadList.clear(); + + for (auto _script : backend->loadedScripts) + { + auto _thread = new LuaThread(_console); + + _thread->exeScript = _script; + _thread->runInterval = backend->frameLimit; + + _threadList.append(_thread); + } + + for (auto _thread : _threadList) + _thread->start(); + } +} + +void MainWindow::latchEvent() +{ + // Try to latch into the process, if successful; + + if (MemoryLib::LatchProcess(_currGame.exeName.toStdString(), _currGame.baseAddress, _currGame.isBigEndian)) + { + // Hide the wait dialog, stop the timer. + + _waitWindow->hide(); + latchTimer->stop(); + + // Continue with Backend Execution. + + connectEvent(); + } +} + +void MainWindow::runEvent() +{ + // The main script thread. + // Only runs if single-threaded. + + if (!_threadBool) + { + for (int i = 0; i < backend->loadedScripts.size(); i++) + { + auto _script = backend->loadedScripts[i]; + + if (_script->frameFunction) + { + auto _result = _script->frameFunction(); + + if (!_result.valid()) + { + sol::error _err = _result; + + auto _errStr = QString(_err.what()); + _console->printMessage(_errStr + "
", 3); + + backend->loadedScripts.erase(backend->loadedScripts.begin() + i); + } + } + } + } + + // If the interval changes, apply the changes to all script threads. + + else if (_threadList[0]->runInterval != backend->frameLimit) + for (auto _thread : _threadList) + _thread->runInterval = backend->frameLimit; + + // If the interval changes, apply this change. + + if (_runTimer->interval() != backend->frameLimit) + _runTimer->setInterval(backend->frameLimit); + + // If auto-reload is enabled and the process + // is lost, activate the reload event. + + // This is OS-specific and only works in Windows + // at this moment. This will be made Linux-compliant. + + if (_autoBool) + { + #if defined(_WIN32) || defined(_WIN64) + DWORD _retCode = 0; + GetExitCodeProcess(MemoryLib::PHandle, &_retCode); + + if (_retCode != STILL_ACTIVE) + reloadEvent(); + #endif + } +} + +// CONTEXT CONSTRUCTOR EVENTS + + +void MainWindow::scriptContextEvent(QPoint point) +{ + // This is also dumb. + + QMenu _contextScript; + + QAction _reloadAction(tr("Refresh List")); + QAction _folderAction(tr("Open Script Folder...")); + + QAction _addAction(tr("New Script...")); + QAction _editAction(tr("Edit Script...")); + QAction _deleteAction(tr("Delete Script...")); + + connect(&_addAction, SIGNAL(triggered()), this, SLOT(newScriptEvent())); + connect(&_editAction, SIGNAL(triggered()), this, SLOT(editScriptEvent())); + connect(&_deleteAction, SIGNAL(triggered()), this, SLOT(deleteScriptEvent())); + connect(&_reloadAction, SIGNAL(triggered()), this, SLOT(refreshScriptEvent())); + connect(&_folderAction, SIGNAL(triggered()), this, SLOT(folderOpenEvent())); + + _contextScript.addAction(&_reloadAction); + _contextScript.addAction(&_folderAction); + _contextScript.addSeparator(); + + if (ui->scriptWidget->currentItem() == nullptr) + { + _editAction.setEnabled(false); + _deleteAction.setEnabled(false); + } + + _contextScript.addAction(&_addAction); + _contextScript.addAction(&_editAction); + _contextScript.addAction(&_deleteAction); + + _contextScript.exec(ui->scriptWidget->mapToGlobal(point)); +} + +// CONTEXT TRIGGER EVENTS + +void MainWindow::newScriptEvent() +{ + // Figure out what path we are working with. + // The same shit as parseScript(). + + auto _path = _currGame.scriptPath; + + if (_path.at(0) == '/' || _path.at(0) == '\\') + _path = _basePath + _path; + + // Construct the new Lua filename. + + auto _name = _path + "\\LuaFile-" + QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss") + ".lua"; + + // Open the file. + + QFile _luaFile(_name); + + // Total abomination. + // But eh, as long as it works, + // I do not care. + + // Construct the template. + + QString _luaTemplate = + + "LUAGUI_NAME = \"\"\n" + "LUAGUI_AUTH = \"\"\n" + "LUAGUI_DESC = \"\"\n" + "\n" + "function _OnInit()\n" + "end\n" + "\n" + "function _OnFrame()\n" + "end\n"; + + // Write the template to the new file and refresh the list. + + if (_luaFile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + QTextStream _txtStream(&_luaFile); + + _txtStream << _luaTemplate; + _luaFile.close(); + } + + parseScript(); + + // Open the file for editing. + + QDesktopServices::openUrl(QUrl::fromLocalFile(_name)); +} + +void MainWindow::editScriptEvent() +{ + auto _data = ui->scriptWidget->currentItem()->data(0, 1807); + QDesktopServices::openUrl(QUrl::fromLocalFile(_data.toString())); +} + +void MainWindow::deleteScriptEvent() +{ + auto _data = ui->scriptWidget->currentItem()->data(0, 1807); + QFile _tmpFile(_data.toString()); + + _tmpFile.remove(); + parseScript(); +} + +void MainWindow::refreshScriptEvent() { parseScript(); } + +void MainWindow::folderOpenEvent() +{ + // Figure out what path we are working with. + // The same shit as parseScript(). + + auto _path = _currGame.scriptPath; + + if (_path.at(0) == '/' || _path.at(0) == '\\') + _path = _basePath + _path; + + // Open it. + + QDesktopServices::openUrl(QUrl::fromLocalFile(_path)); +} + +void MainWindow::languageEvent() +{ + QObject* _senderButton = sender(); + + if (_senderButton == ui->en_US) + _language = "en_US"; + + if (_senderButton == ui->tr_TR) + _language = "tr_TR"; + + _prefTable["language"] = _language.toStdString(); + serializePref(); + + qApp->removeTranslator(&_translator); + + QString _baseLang = QApplication::applicationDirPath(); + _baseLang.append("/languages/"); + + if(_translator.load(_baseLang + _language)) + qApp->installTranslator(&_translator); + + ui->retranslateUi(this); + + // I know, I know. This is REALLY super duper + // NOT OKAY! But hey, I am lazy, and this should, work. + + _console->close(); + + _aboutDiag = new AboutFrontend(this); + _patreonDiag = new AboutPatreon(this); + + _console = new Console(this); + _waitWindow = new WaitDialog(this); + + // I hate QT sometimes. + + QStringList _labelList = { tr("Title"), tr("Author(s)"), tr("Description") }; + ui->scriptWidget->setHeaderLabels(_labelList); +} + +void MainWindow::showAbout() +{ + _aboutDiag->show(); +} + +void MainWindow::showPatreon() +{ + _patreonDiag->show(); +} + +// MISC + +void MainWindow::serializePref() +{ + auto _tomlDir = QString(_basePath + "\\configs\\prefConfig.toml"); + + stringstream _str; + QFile _tomlFile(_tomlDir); + + _str << "[Preferences]\n"; + _str << _prefTable; + QString _writeStr = QString::fromStdString(_str.str()); + + _tomlFile.open(QIODevice::WriteOnly); + _tomlFile.write(_writeStr.toUtf8()); +} + + diff --git a/MainWindow.hpp b/MainWindow.hpp new file mode 100644 index 0000000..0c200ac --- /dev/null +++ b/MainWindow.hpp @@ -0,0 +1,115 @@ +#ifndef MAINWINDOW_H +#define MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +QT_BEGIN_NAMESPACE + namespace Ui { class MainWindow; } +QT_END_NAMESPACE + +class MainWindow : public QMainWindow +{ + struct QGameInfo + { + QString gameName; + QString exeName; + QString scriptPath; + uint64_t baseAddress; + uint64_t offset; + bool isBigEndian; + }; + + Q_OBJECT + + public: + QTimer* latchTimer; + + LuaBackend* backend; + LuaBackend* backendFake; + + MainWindow(QWidget *parent = nullptr); + ~MainWindow(); + + public slots: + void consoleToggle(); + + private slots: + void runEvent(); + void stopEvent(); + void autoToggle(); + void latchEvent(); + void startEvent(); + void darkToggle(); + void reloadEvent(); + void connectEvent(); + void threadToggle(); + void gameClickEvent(int); + void scriptClickEvent(QTreeWidgetItem*, int); + + void scriptContextEvent(QPoint); + + void newScriptEvent(); + void editScriptEvent(); + void deleteScriptEvent(); + void refreshScriptEvent(); + void folderOpenEvent(); + void languageEvent(); + + void showAbout(); + void showPatreon(); + + +private: + toml::value _prefTable; + toml::value _gameToml; + + QPalette _darkPal; + QPalette _lightPal; + + bool _autoBool; + bool _threadBool; + bool _consoleBool; + bool _darkPalBool; + + QString _language; + + Console* _console; + WaitDialog* _waitWindow; + AboutFrontend* _aboutDiag; + AboutPatreon* _patreonDiag; + + QTimer* _runTimer; + QList _threadList; + + QString _basePath; + QGameInfo _currGame; + + int parseGame(); + int parseScript(); + + void serializePref(); + + QTranslator _translator; + + Ui::MainWindow *ui; + +}; + +#endif // MAINWINDOW_H diff --git a/MainWindow.ui b/MainWindow.ui new file mode 100644 index 0000000..3c868be --- /dev/null +++ b/MainWindow.ui @@ -0,0 +1,259 @@ + + + MainWindow + + + + 0 + 0 + 555 + 365 + + + + + 555 + 365 + + + + LuaFrontend [v1.15 | STABLE] + + + + :/resources/iconMain.ico:/resources/iconMain.ico + + + + + + + + 5 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 2 + 0 + + + + Games: + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::CustomContextMenu + + + + + + + + + + + 6 + 0 + + + + Scripts: + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::CustomContextMenu + + + 16 + + + 0 + + + 3 + + + false + + + 35 + + + + 1 + + + + + 2 + + + + + 3 + + + + + + + + + + + + + + + + 0 + 0 + 555 + 21 + + + + + Engine + + + + + + + + + + + + Edit + + + + Languages + + + + + + + + + + + + + false + + + Show Console... + + + + + Enable Auto-Reload + + + + + Start Engine + + + + + false + + + Reload Engine + + + + + false + + + Stop Engine + + + + + Switch to Dark Mode + + + + + Enable Multi-Threading + + + + + false + + + false + + + English + + + + + false + + + Turkish + + + + + + diff --git a/README.md b/README.md index cbd3065..1872c71 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,80 @@ # LuaFrontend -An all-encompassing GUI program to allow for RAM modifications through Lua. + +LuaFrontend is a standalone script interpreter for PC games. It attaches itself to the PC application and executes Lua scripts. +It is fully compatible with LuaEngine. + +## How do I use LuaEngine mod that I have downloaded with LuaFrontend? + +To use a LuaEngine script, all you have to do is to right click the scripts section of the game you want, and click "**Open Script Folder**", +then drop the script in question to the opened folder. That's it! + +However, LuaEngine also has I/O capability. So if a mod you have downloaded also has "**io_load**" or "**io_packages**" directories included, +you would need to drop those folders to that folder as well. + +## How do I use libraries made for Lua with LuaEngine? + +The libraries you would need to use must be 5.4.3 compliant. In addition, if the libraries need to be compiled, they must be compiled +for x86_64 and with Lua 5.4.3 with the MSVC 2019 compiler. + +Put the libraries on the "**io_packages**" folder in the script folder of your game. To reference them, you can then use the ``require`` command. +Exampe being, if I want to use ``socket.http`` from LuaSocket, which I put in ``scripts/io_packages/LuaSocket/``, I would need to do: + +```lua +local http = require("LuaSocket/socket.http") +``` + +That's it! + +## How do I use LuaFrontend to create a LuaEngine mod myself? + +Right clock the scripts section of the game you want to make a script for and click "**New Script**". +The script will be created and opened automatically. You should see something like this: + +```lua +LUAGUI_NAME = "" +LUAGUI_AUTH = "" +LUAGUI_DESC = "" + +function _OnInit() + -- Code here executes on script load. +end + +function _OnFrame() + -- Code here executes on every frame. +end +``` + +The "LUAGUI" globals are for LuaFrontend. They signify the Title, Author and Description sections respectively. +They are optional globals and not required for operation. + +The script in question should have at least one of these functions to work. The "**\_OnInit**" function is executed when the script is first loaded, +and the "**\_OnFrame**" function is executed every frame. So put the things you want to happen every frame into the "**\_OnFrame**" function. + +That is the minimum you would need to have a functioning script. The rest is on you. The scripts in LuaEngine function just as if they were regular Lua scripts. +Because... they kind of are! + +In **DOCUMENT.md**, you can find the cheatsheet to all LuaEngine specific functions. + +## How do I add games to LuaFrontend + +Simply open the "**configs/gameConfig.toml**" file and edit it accordingly. You can copy-paste an already-existing game as a template. +The ability to add games from the GUI will come soon-ish. + +## A script errors out. How can I see what's wrong + +Hover over the script with your mouse to see warnings. +If prompted by the tooltip, double click the script to show a more detailed error. + +## Important Notes to using LuaEngine + +- All values are unsigned. +- There is no limit for the amount of scripts loaded at this moment. + +## Third Party Libraries + +https://qt.io/ (Qt 5.15.2) +http://www.lua.org/ (Lua 5.4.3) +https://github.com/ThePhD/sol2 +https://github.com/d-bahr/CRCpp +https://github.com/ToruNiina/toml11 +https://github.com/discord/discord-rpc diff --git a/Resources.qrc b/Resources.qrc new file mode 100644 index 0000000..e840105 --- /dev/null +++ b/Resources.qrc @@ -0,0 +1,9 @@ + + + resources/error.png + resources/good.png + resources/iconMain.png + resources/warning.png + resources/iconPatreon.png + + diff --git a/WaitDialog.cpp b/WaitDialog.cpp new file mode 100644 index 0000000..1596d5e --- /dev/null +++ b/WaitDialog.cpp @@ -0,0 +1,29 @@ +#include +#include + +#include + +MainWindow* _rootParent; + +WaitDialog::WaitDialog(QWidget *parent) : QDialog(parent), ui(new Ui::WaitDialog) +{ + ui->setupUi(this); + + _rootParent = (MainWindow*)parent; + + connect(this, SIGNAL(rejected()), this, SLOT(rejectEvent())); + connect(ui->abortButton, SIGNAL(pressed()), this, SLOT(rejectEvent())); + + setWindowFlags(Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint); +} + +WaitDialog::~WaitDialog() +{ + delete ui; +} + +void WaitDialog::rejectEvent() +{ + _rootParent->latchTimer->stop(); + this->close(); +} diff --git a/WaitDialog.hpp b/WaitDialog.hpp new file mode 100644 index 0000000..efd4c94 --- /dev/null +++ b/WaitDialog.hpp @@ -0,0 +1,25 @@ +#ifndef WAITDIALOG_HPP +#define WAITDIALOG_HPP + +#include + +namespace Ui { +class WaitDialog; +} + +class WaitDialog : public QDialog +{ + Q_OBJECT + + public: + explicit WaitDialog(QWidget *parent = nullptr); + ~WaitDialog(); + + private: + Ui::WaitDialog *ui; + + private slots: + void rejectEvent(); +}; + +#endif // WAITDIALOG_HPP diff --git a/WaitDialog.ui b/WaitDialog.ui new file mode 100644 index 0000000..e8102e2 --- /dev/null +++ b/WaitDialog.ui @@ -0,0 +1,57 @@ + + + WaitDialog + + + Qt::WindowModal + + + + 0 + 0 + 231 + 94 + + + + Qt::NoContextMenu + + + Please Wait... + + + + :/resources/iconMain.ico:/resources/iconMain.ico + + + + + + Please Wait... Trying to attach to process... + + + + + + + 0 + + + 0 + + + + + + + Abort + + + + + + + + + + diff --git a/Windows.rc b/Windows.rc new file mode 100644 index 0000000..5c9f8bb --- /dev/null +++ b/Windows.rc @@ -0,0 +1,31 @@ +IDI_ICON1 ICON DISCARDABLE "resources/iconMain.ico" + +#include +#include "version.h" + +VS_VERSION_INFO VERSIONINFO +FILEVERSION VER_FILEVERSION +PRODUCTVERSION VER_PRODUCTVERSION +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + BEGIN + VALUE "CompanyName", VER_COMPANYNAME_STR + VALUE "FileDescription", VER_FILEDESCRIPTION_STR + VALUE "FileVersion", VER_FILEVERSION_STR + VALUE "InternalName", VER_INTERNALNAME_STR + VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR + VALUE "LegalTrademarks1", VER_LEGALTRADEMARKS1_STR + VALUE "LegalTrademarks2", VER_LEGALTRADEMARKS2_STR + VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR + VALUE "ProductName", VER_PRODUCTNAME_STR + VALUE "ProductVersion", VER_PRODUCTVERSION_STR + END + END + + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1252 + END +END diff --git a/configs/gameConfig.toml b/configs/gameConfig.toml new file mode 100644 index 0000000..4d95418 --- /dev/null +++ b/configs/gameConfig.toml @@ -0,0 +1,47 @@ +[GameEntry00] +Title = "Kingdom Hearts [GL]" +Path = "/scripts/kh1gl/" +Address = "0" +Offset = "3A0606" +BigEndian = false +Executable = "KINGDOM HEARTS FINAL MIX.exe" + +[GameEntry01] +Title = "Kingdom Hearts II [GL]" +Path = "/scripts/kh2gl/" +Address = "0" +Offset = "56450E" +BigEndian = false +Executable = "KINGDOM HEARTS II FINAL MIX.exe" + +[GameEntry02] +Title = "Kingdom Hearts II [JP]" +Path = "/scripts/kh2jp/" +Address = "0" +Offset = "56350E" +BigEndian = false +Executable = "KINGDOM HEARTS II FINAL MIX.exe" + +[GameEntry03] +Title = "RPCS3" +Path = "/scripts/rpcs3/" +Address = "300010000" +Offset = "0" +BigEndian = true +Executable = "RPCS3.exe" + +[GameEntry04] +Title = "Kingdom Hearts Birth by Sleep [GL]" +Path = "/scripts/khbbs/" +Address = "0" +Offset = "60E334" +BigEndian = false +Executable = "KINGDOM HEARTS Birth by Sleep FINAL MIX.exe" + +[GameEntry05] +Title = "Kingdom Hearts Re:Chain of Memories [GL]" +Path = "/scripts/khcom/" +Address = "0" +Offset = "4E4660" +BigEndian = false +Executable = "KINGDOM HEARTS Re_Chain of Memories.exe" diff --git a/configs/prefConfig.toml b/configs/prefConfig.toml new file mode 100644 index 0000000..6295806 --- /dev/null +++ b/configs/prefConfig.toml @@ -0,0 +1,6 @@ +[Preferences] +autoBool = false +threadBool = false +consoleBool = false +darkPalBool = false +language = "en_US" diff --git a/include/DCInstance.hpp b/include/DCInstance.hpp new file mode 100644 index 0000000..be00d5c --- /dev/null +++ b/include/DCInstance.hpp @@ -0,0 +1,52 @@ +#pragma once + +#include +#include +#include +#include + +using namespace std; + +class DCInstance { +public: + static inline DiscordRichPresence Presence; + + static void InitializeRPC(const char* applicationID) + { + Discord_Initialize(applicationID, NULL, 1, NULL); + + memset(&DCInstance::Presence, 0, sizeof(DCInstance::Presence)); + + auto _currTime = chrono::system_clock::now().time_since_epoch(); + auto _secondCast = chrono::duration_cast(_currTime); + + DCInstance::Presence.startTimestamp = _secondCast.count(); + Discord_UpdatePresence(&DCInstance::Presence); + } + + static void UpdateDetails(const char* input) + { + DCInstance::Presence.details = input; + Discord_UpdatePresence(&DCInstance::Presence); + } + + static void UpdateState(const char* input) + { + DCInstance::Presence.state = input; + Discord_UpdatePresence(&DCInstance::Presence); + } + + static void UpdateLImage(const char* key, const char* text) + { + DCInstance::Presence.largeImageKey = key; + DCInstance::Presence.largeImageText = text; + Discord_UpdatePresence(&DCInstance::Presence); + } + + static void UpdateSImage(const char* key, const char* text) + { + DCInstance::Presence.smallImageKey = key; + DCInstance::Presence.smallImageText = text; + Discord_UpdatePresence(&DCInstance::Presence); + } +}; \ No newline at end of file diff --git a/include/MemoryLib.hpp b/include/MemoryLib.hpp new file mode 100644 index 0000000..fb49db4 --- /dev/null +++ b/include/MemoryLib.hpp @@ -0,0 +1,283 @@ +#ifndef MEMORYLIB +#define MEMORYLIB + +#if defined(_WIN32) || defined(_WIN64) + #include + #include + #include "TlHelp32.h" +#endif + +#include +#include +#include + +using namespace std; + +class MemoryLib +{ + private: + + #if defined(_WIN32) || defined(_WIN64) + static inline STARTUPINFOA _sInfo; + static inline PROCESS_INFORMATION _pInfo; + #endif + + public: + + static inline uint64_t ExecAddress; + static inline uint64_t BaseAddress; + static inline bool BigEndian = false; + + #if defined(_WIN32) || defined(_WIN64) + static inline DWORD PIdentifier = 0; + static inline HANDLE PHandle = NULL; + static inline char PName[MAX_PATH]; + + static HMODULE FindBaseAddr(HANDLE InputHandle, string InputName) + { + HMODULE hMods[1024]; + DWORD cbNeeded; + unsigned int i; + + if (EnumProcessModules(InputHandle, hMods, sizeof(hMods), &cbNeeded)) + { + for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) + { + TCHAR szModName[MAX_PATH]; + if (GetModuleFileNameEx(InputHandle, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) + { + wstring wstrModName = szModName; + wstring wstrModContain = wstring(InputName.begin(), InputName.end()); + + if (wstrModName.find(wstrModContain) != string::npos) + return hMods[i]; + } + } + } + + return nullptr; + } + + static DWORD FindProcessId(const std::wstring& processName) + { + PROCESSENTRY32 processInfo; + processInfo.dwSize = sizeof(processInfo); + + HANDLE processesSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (processesSnapshot == INVALID_HANDLE_VALUE) + return 0; + + Process32First(processesSnapshot, &processInfo); + if (!processName.compare(processInfo.szExeFile)) + { + CloseHandle(processesSnapshot); + return processInfo.th32ProcessID; + } + + while (Process32Next(processesSnapshot, &processInfo)) + { + if (!processName.compare(processInfo.szExeFile)) + { + CloseHandle(processesSnapshot); + return processInfo.th32ProcessID; + } + } + + CloseHandle(processesSnapshot); + return 0; + } + static int ExecuteProcess(string InputName, uint64_t InputAddress, bool InputEndian) + { + ZeroMemory(&_sInfo, sizeof(_sInfo)); _sInfo.cb = sizeof(_sInfo); + ZeroMemory(&_pInfo, sizeof(_pInfo)); + + if (CreateProcessA(InputName.c_str(), NULL, NULL, NULL, TRUE, 0, NULL, NULL, &_sInfo, &_pInfo) == 0) + return -1; + + BaseAddress = InputAddress; + BigEndian = InputEndian; + + return 0; + }; + static bool LatchProcess(string InputName, uint64_t InputAddress, bool InputEndian) + { + ZeroMemory(&_sInfo, sizeof(_sInfo)); _sInfo.cb = sizeof(_sInfo); + ZeroMemory(&_pInfo, sizeof(_pInfo)); + + PIdentifier = FindProcessId(wstring(InputName.begin(), InputName.end())); + PHandle = OpenProcess(PROCESS_ALL_ACCESS, false, PIdentifier); + + GetProcessImageFileNameA(MemoryLib::PHandle, PName, MAX_PATH); + BaseAddress = InputAddress; + + ExecAddress = (uint64_t)FindBaseAddr(PHandle, PName); + BigEndian = InputEndian; + + if (PHandle == NULL) + return false; + + return true; + }; + static void ExternProcess(DWORD InputID, HANDLE InputH, uint64_t InputAddress) + { + PIdentifier = InputID; + PHandle = InputH; + + GetProcessImageFileNameA(MemoryLib::PHandle, PName, MAX_PATH); + + BaseAddress = InputAddress; + ExecAddress = (uint64_t)FindBaseAddr(PHandle, PName); + }; + #endif + + static void SetBaseAddr(uint64_t InputAddress) + { + BaseAddress = InputAddress; + } + + // Reader Functions + + static uint8_t ReadByte(uint64_t _addr, bool _absolute = false) { return ReadBytes(_addr, 1, _absolute)[0]; } + static vector ReadBytes(uint64_t _addr, int _len, bool _absolute = false) + { + vector _buffer; + _buffer.resize(_len); + + ReadProcessMemory(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), _buffer.data(), _len, 0); + return _buffer; + } + static uint16_t ReadShort(uint64_t _addr, bool _absolute = false) + { + auto _buffer = ReadBytes(_addr, 2, _absolute); + + if (BigEndian) + return (_buffer[0] << 8) | _buffer[1]; + else + return (_buffer[1] << 8) | _buffer[0]; + } + static uint32_t ReadInt(uint64_t _addr, bool _absolute = false) + { + auto _buffer = ReadBytes(_addr, 4, _absolute); + + if (BigEndian) + return (_buffer[0] << 24) | (_buffer[1] << 16) | (_buffer[2] << 8) | (_buffer[3]); + else + return (_buffer[3] << 24) | (_buffer[2] << 16) | (_buffer[1] << 8) | (_buffer[0]); + } + static uint64_t ReadLong(uint64_t _addr, bool _absolute = false) + { + auto _buffer = ReadBytes(_addr, 8, _absolute); + + if (BigEndian) + return ((uint64_t)_buffer[0] << 56) | ((uint64_t)_buffer[1] << 48) | ((uint64_t)_buffer[2] << 40) | ((uint64_t)_buffer[3] << 32) | ((uint64_t)_buffer[4] << 24) | ((uint64_t)_buffer[5] << 16) | ((uint64_t)_buffer[6] << 8) | ((uint64_t)_buffer[7]); + + else + return ((uint64_t)_buffer[7] << 56) | ((uint64_t)_buffer[6] << 48) | ((uint64_t)_buffer[5] << 40) | ((uint64_t)_buffer[4] << 32) | ((uint64_t)_buffer[3] << 24) | ((uint64_t)_buffer[2] << 16) | ((uint64_t)_buffer[1] << 8) | ((uint64_t)_buffer[0]); + } + static float ReadFloat(uint64_t _addr, bool _absolute = false) + { + auto _value = ReadInt(_addr, _absolute); + auto _return = *reinterpret_cast(&_value); + return _return; + } + static bool ReadBool(uint64_t _addr, bool _absolute = false) + { + auto _value = ReadByte(_addr, _absolute); + return _value == 0 ? false : true; + } + static string ReadString(uint64_t _addr, int _len, bool _absolute = false) + { + auto _value = ReadBytes(_addr, _len, _absolute); + string _output(_value.begin(), _value.end()); + return _output; + } + + // Writer Functions + + static void WriteByte(uint64_t _addr, uint8_t _val, bool _absolute = false) + { + if (WriteProcessMemory(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), &_val, 1, 0) == 0) + { + DWORD _protectOld = 0; + VirtualProtectEx(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), 256, PAGE_READWRITE, &_protectOld); + WriteProcessMemory(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), &_val, 1, 0); + } + } + static void WriteBytes(uint64_t _addr, vector _val, bool _absolute = false) + { + if (WriteProcessMemory(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), _val.data(), _val.size(), 0) == 0) + { + DWORD _protectOld = 0; + VirtualProtectEx(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), 256, PAGE_READWRITE, &_protectOld); + WriteProcessMemory(PHandle, _absolute ? (void*)(_addr) : (void*)(_addr + BaseAddress), _val.data(), _val.size(), 0); + } + } + static void WriteShort(uint64_t _addr, uint16_t _val, bool _absolute = false) + { + vector _write(2); + + for (uint64_t i = 0; i < 2; i++) + { + if (BigEndian) + _write[1 - i] = (_val >> (i * 8)) & 0xFF; + + else + _write[i] = (_val >> (i * 8)) & 0xFF; + } + + WriteBytes(_addr, _write, _absolute); + _write.clear(); + } + static void WriteInt(uint64_t _addr, uint32_t _val, bool _absolute = false) + { + vector _write(4); + + for (uint64_t i = 0; i < 4; i++) + { + if (BigEndian) + _write[3 - i] = (_val >> (i * 8)) & 0xFF; + + else + _write[i] = (_val >> (i * 8)) & 0xFF; + } + + WriteBytes(_addr, _write, _absolute); + _write.clear(); + } + static void WriteLong(uint64_t _addr, uint64_t _val, bool _absolute = false) + { + vector _write(8); + + for (uint64_t i = 0; i < 8; i++) + { + if (BigEndian) + _write[1 - i] = (_val >> (i * 8)) & 0xFF; + + else + _write[i] = (_val >> (i * 8)) & 0xFF; + } + + WriteBytes(_addr, _write, _absolute); + _write.clear(); + } + static void WriteFloat(uint64_t _addr, float _val, bool _absolute = false) + { + auto _value = *reinterpret_cast(&_val); + WriteInt(_addr, _value, _absolute); + } + static void WriteBool(uint64_t _addr, bool _val, bool _absolute = false) { _val == true ? WriteByte(_addr, 1, _absolute) : WriteByte(_addr, 0, _absolute); } + static void WriteString(uint64_t _addr, string _val, bool _absolute = false) + { + vector _value(_val.begin(), _val.end()); + WriteBytes(_addr, _value, _absolute); + } + + // Misc. Functions + + static void WriteExec(uint64_t _addr, vector _val) + { + WriteProcessMemory(PHandle, (void*)(_addr + ExecAddress), _val.data(), _val.size(), 0); + } + +}; +#endif diff --git a/include/Operator32Lib.hpp b/include/Operator32Lib.hpp new file mode 100644 index 0000000..bfe247a --- /dev/null +++ b/include/Operator32Lib.hpp @@ -0,0 +1,28 @@ +#ifndef OP32LIB +#define OP32LIB + +#include +#include +#include +#include +#include "TlHelp32.h" + +using namespace std; + +class Operator32Lib +{ +public: + static uint32_t UnsignedShift32(uint32_t base, uint32_t shift) + { + string _inBinary = bitset<32>(base).to_string(); + string _outBinary = "00000000000000000000000000000000"; + + for (uint32_t i = 0; i < 32 - shift; i++) + _outBinary[i] = _inBinary[i + shift]; + + uint32_t _out = bitset<32>(_outBinary).to_ulong(); + return _out; + } +}; + +#endif \ No newline at end of file diff --git a/include/crcpp/CRC32.h b/include/crcpp/CRC32.h new file mode 100644 index 0000000..149218a --- /dev/null +++ b/include/crcpp/CRC32.h @@ -0,0 +1,2054 @@ +/** + @file CRC.h + @author Daniel Bahr + @version 1.1.0.0 + @copyright + @parblock + CRC++ + Copyright (c) 2021, Daniel Bahr + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of CRC++ nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + @endparblock +*/ + +/* + CRC++ can be configured by setting various #defines before #including this header file: + + #define crcpp_uint8 - Specifies the type used to store CRCs that have a width of 8 bits or less. + This type is not used in CRC calculations. Defaults to ::std::uint8_t. + #define crcpp_uint16 - Specifies the type used to store CRCs that have a width between 9 and 16 bits (inclusive). + This type is not used in CRC calculations. Defaults to ::std::uint16_t. + #define crcpp_uint32 - Specifies the type used to store CRCs that have a width between 17 and 32 bits (inclusive). + This type is not used in CRC calculations. Defaults to ::std::uint32_t. + #define crcpp_uint64 - Specifies the type used to store CRCs that have a width between 33 and 64 bits (inclusive). + This type is not used in CRC calculations. Defaults to ::std::uint64_t. + #define crcpp_size - This type is used for loop iteration and function signatures only. Defaults to ::std::size_t. + #define CRCPP_USE_NAMESPACE - Define to place all CRC++ code within the ::CRCPP namespace. + #define CRCPP_BRANCHLESS - Define to enable a branchless CRC implementation. The branchless implementation uses a single integer + multiplication in the bit-by-bit calculation instead of a small conditional. The branchless implementation + may be faster on processor architectures which support single-instruction integer multiplication. + #define CRCPP_USE_CPP11 - Define to enables C++11 features (move semantics, constexpr, static_assert, etc.). + #define CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS - Define to include definitions for little-used CRCs. +*/ + +#ifndef CRCPP_CRC_H_ +#define CRCPP_CRC_H_ + +#include // Includes CHAR_BIT +#ifdef CRCPP_USE_CPP11 +#include // Includes ::std::size_t +#include // Includes ::std::uint8_t, ::std::uint16_t, ::std::uint32_t, ::std::uint64_t +#else +#include // Includes size_t +#include // Includes uint8_t, uint16_t, uint32_t, uint64_t +#endif +#include // Includes ::std::numeric_limits +#include // Includes ::std::move + +#ifndef crcpp_uint8 +# ifdef CRCPP_USE_CPP11 + /// @brief Unsigned 8-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint8 ::std::uint8_t +# else + /// @brief Unsigned 8-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint8 uint8_t +# endif +#endif + +#ifndef crcpp_uint16 +# ifdef CRCPP_USE_CPP11 + /// @brief Unsigned 16-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint16 ::std::uint16_t +# else + /// @brief Unsigned 16-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint16 uint16_t +# endif +#endif + +#ifndef crcpp_uint32 +# ifdef CRCPP_USE_CPP11 + /// @brief Unsigned 32-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint32 ::std::uint32_t +# else + /// @brief Unsigned 32-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint32 uint32_t +# endif +#endif + +#ifndef crcpp_uint64 +# ifdef CRCPP_USE_CPP11 + /// @brief Unsigned 64-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint64 ::std::uint64_t +# else + /// @brief Unsigned 64-bit integer definition, used primarily for parameter definitions. +# define crcpp_uint64 uint64_t +# endif +#endif + +#ifndef crcpp_size +# ifdef CRCPP_USE_CPP11 + /// @brief Unsigned size definition, used for specifying data sizes. +# define crcpp_size ::std::size_t +# else + /// @brief Unsigned size definition, used for specifying data sizes. +# define crcpp_size size_t +# endif +#endif + +#ifdef CRCPP_USE_CPP11 + /// @brief Compile-time expression definition. +# define crcpp_constexpr constexpr +#else + /// @brief Compile-time expression definition. +# define crcpp_constexpr const +#endif + +#ifdef CRCPP_USE_NAMESPACE +namespace CRCPP +{ +#endif + +/** + @brief Static class for computing CRCs. + @note This class supports computation of full and multi-part CRCs, using a bit-by-bit algorithm or a + byte-by-byte lookup table. The CRCs are calculated using as many optimizations as is reasonable. + If compiling with C++11, the constexpr keyword is used liberally so that many calculations are + performed at compile-time instead of at runtime. +*/ +class CRC +{ +public: + // Forward declaration + template + struct Table; + + /** + @brief CRC parameters. + */ + template + struct Parameters + { + CRCType polynomial; ///< CRC polynomial + CRCType initialValue; ///< Initial CRC value + CRCType finalXOR; ///< Value to XOR with the final CRC + bool reflectInput; ///< true to reflect all input bytes + bool reflectOutput; ///< true to reflect the output CRC (reflection occurs before the final XOR) + + Table MakeTable() const; + }; + + /** + @brief CRC lookup table. After construction, the CRC parameters are fixed. + @note A CRC table can be used for multiple CRC calculations. + */ + template + struct Table + { + // Constructors are intentionally NOT marked explicit. + Table(const Parameters & parameters); + +#ifdef CRCPP_USE_CPP11 + Table(Parameters && parameters); +#endif + + const Parameters & GetParameters() const; + + const CRCType * GetTable() const; + + CRCType operator[](unsigned char index) const; + + private: + void InitTable(); + + Parameters parameters; ///< CRC parameters used to construct the table + CRCType table[1 << CHAR_BIT]; ///< CRC lookup table + }; + + // The number of bits in CRCType must be at least as large as CRCWidth. + // CRCType must be an unsigned integer type or a custom type with operator overloads. + template + static CRCType Calculate(const void * data, crcpp_size size, const Parameters & parameters); + + template + static CRCType Calculate(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc); + + template + static CRCType Calculate(const void * data, crcpp_size size, const Table & lookupTable); + + template + static CRCType Calculate(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc); + + template + static CRCType CalculateBits(const void * data, crcpp_size size, const Parameters & parameters); + + template + static CRCType CalculateBits(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc); + + template + static CRCType CalculateBits(const void * data, crcpp_size size, const Table & lookupTable); + + template + static CRCType CalculateBits(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc); + + // Common CRCs up to 64 bits. + // Note: Check values are the computed CRCs when given an ASCII input of "123456789" (without null terminator) +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters< crcpp_uint8, 4> & CRC_4_ITU(); + static const Parameters< crcpp_uint8, 5> & CRC_5_EPC(); + static const Parameters< crcpp_uint8, 5> & CRC_5_ITU(); + static const Parameters< crcpp_uint8, 5> & CRC_5_USB(); + static const Parameters< crcpp_uint8, 6> & CRC_6_CDMA2000A(); + static const Parameters< crcpp_uint8, 6> & CRC_6_CDMA2000B(); + static const Parameters< crcpp_uint8, 6> & CRC_6_ITU(); + static const Parameters< crcpp_uint8, 6> & CRC_6_NR(); + static const Parameters< crcpp_uint8, 7> & CRC_7(); +#endif + static const Parameters< crcpp_uint8, 8> & CRC_8(); +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters< crcpp_uint8, 8> & CRC_8_EBU(); + static const Parameters< crcpp_uint8, 8> & CRC_8_MAXIM(); + static const Parameters< crcpp_uint8, 8> & CRC_8_WCDMA(); + static const Parameters< crcpp_uint8, 8> & CRC_8_LTE(); + static const Parameters & CRC_10(); + static const Parameters & CRC_10_CDMA2000(); + static const Parameters & CRC_11(); + static const Parameters & CRC_11_NR(); + static const Parameters & CRC_12_CDMA2000(); + static const Parameters & CRC_12_DECT(); + static const Parameters & CRC_12_UMTS(); + static const Parameters & CRC_13_BBC(); + static const Parameters & CRC_15(); + static const Parameters & CRC_15_MPT1327(); +#endif + static const Parameters & CRC_16_ARC(); + static const Parameters & CRC_16_BUYPASS(); + static const Parameters & CRC_16_CCITTFALSE(); +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters & CRC_16_CDMA2000(); + static const Parameters & CRC_16_CMS(); + static const Parameters & CRC_16_DECTR(); + static const Parameters & CRC_16_DECTX(); + static const Parameters & CRC_16_DNP(); +#endif + static const Parameters & CRC_16_GENIBUS(); + static const Parameters & CRC_16_KERMIT(); +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters & CRC_16_MAXIM(); + static const Parameters & CRC_16_MODBUS(); + static const Parameters & CRC_16_T10DIF(); + static const Parameters & CRC_16_USB(); +#endif + static const Parameters & CRC_16_X25(); + static const Parameters & CRC_16_XMODEM(); +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters & CRC_17_CAN(); + static const Parameters & CRC_21_CAN(); + static const Parameters & CRC_24(); + static const Parameters & CRC_24_FLEXRAYA(); + static const Parameters & CRC_24_FLEXRAYB(); + static const Parameters & CRC_24_LTEA(); + static const Parameters & CRC_24_LTEB(); + static const Parameters & CRC_24_NRC(); + static const Parameters & CRC_30(); +#endif + static const Parameters & CRC_32(); + static const Parameters & CRC_32_BZIP2(); +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters & CRC_32_C(); +#endif + static const Parameters & CRC_32_MPEG2(); + static const Parameters & CRC_32_POSIX(); +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + static const Parameters & CRC_32_Q(); + static const Parameters & CRC_40_GSM(); + static const Parameters & CRC_64(); +#endif + +#ifdef CRCPP_USE_CPP11 + CRC() = delete; + CRC(const CRC & other) = delete; + CRC & operator=(const CRC & other) = delete; + CRC(CRC && other) = delete; + CRC & operator=(CRC && other) = delete; +#endif + +private: +#ifndef CRCPP_USE_CPP11 + CRC(); + CRC(const CRC & other); + CRC & operator=(const CRC & other); +#endif + + template + static IntegerType Reflect(IntegerType value, crcpp_uint16 numBits); + + template + static CRCType Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput); + + template + static CRCType UndoFinalize(CRCType remainder, CRCType finalXOR, bool reflectOutput); + + template + static CRCType CalculateRemainder(const void * data, crcpp_size size, const Parameters & parameters, CRCType remainder); + + template + static CRCType CalculateRemainder(const void * data, crcpp_size size, const Table & lookupTable, CRCType remainder); + + template + static CRCType CalculateRemainderBits(unsigned char byte, crcpp_size numBits, const Parameters & parameters, CRCType remainder); +}; + +/** + @brief Returns a CRC lookup table construct using these CRC parameters. + @note This function primarily exists to allow use of the auto keyword instead of instantiating + a table directly, since template parameters are not inferred in constructors. + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC lookup table +*/ +template +inline CRC::Table CRC::Parameters::MakeTable() const +{ + // This should take advantage of RVO and optimize out the copy. + return CRC::Table(*this); +} + +/** + @brief Constructs a CRC table from a set of CRC parameters + @param[in] params CRC parameters + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC +*/ +template +inline CRC::Table::Table(const Parameters & params) : + parameters(params) +{ + InitTable(); +} + +#ifdef CRCPP_USE_CPP11 +/** + @brief Constructs a CRC table from a set of CRC parameters + @param[in] params CRC parameters + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC +*/ +template +inline CRC::Table::Table(Parameters && params) : + parameters(::std::move(params)) +{ + InitTable(); +} +#endif + +/** + @brief Gets the CRC parameters used to construct the CRC table + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC parameters +*/ +template +inline const CRC::Parameters & CRC::Table::GetParameters() const +{ + return parameters; +} + +/** + @brief Gets the CRC table + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC table +*/ +template +inline const CRCType * CRC::Table::GetTable() const +{ + return table; +} + +/** + @brief Gets an entry in the CRC table + @param[in] index Index into the CRC table + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC table entry +*/ +template +inline CRCType CRC::Table::operator[](unsigned char index) const +{ + return table[index]; +} + +/** + @brief Initializes a CRC table. + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC +*/ +template +inline void CRC::Table::InitTable() +{ + // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) + static crcpp_constexpr CRCType BIT_MASK((CRCType(1) << (CRCWidth - CRCType(1))) | + ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1))); + + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); + + CRCType crc; + unsigned char byte = 0; + + // Loop over each dividend (each possible number storable in an unsigned char) + do + { + crc = CRC::CalculateRemainder(&byte, sizeof(byte), parameters, CRCType(0)); + + // This mask might not be necessary; all unit tests pass with this line commented out, + // but that might just be a coincidence based on the CRC parameters used for testing. + // In any case, this is harmless to leave in and only adds a single machine instruction per loop iteration. + crc &= BIT_MASK; + + if (!parameters.reflectInput && CRCWidth < CHAR_BIT) + { + // Undo the special operation at the end of the CalculateRemainder() + // function for non-reflected CRCs < CHAR_BIT. + crc = static_cast(crc << SHIFT); + } + + table[byte] = crc; + } + while (++byte); +} + +/** + @brief Computes a CRC. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bytes + @param[in] parameters CRC parameters + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Parameters & parameters) +{ + CRCType remainder = CalculateRemainder(data, size, parameters, parameters.initialValue); + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} +/** + @brief Appends additional data to a previous CRC calculation. + @note This function can be used to compute multi-part CRCs. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bytes + @param[in] parameters CRC parameters + @param[in] crc CRC from a previous calculation + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc) +{ + CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); + + remainder = CalculateRemainder(data, size, parameters, remainder); + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} + +/** + @brief Computes a CRC via a lookup table. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bytes + @param[in] lookupTable CRC lookup table + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Table & lookupTable) +{ + const Parameters & parameters = lookupTable.GetParameters(); + + CRCType remainder = CalculateRemainder(data, size, lookupTable, parameters.initialValue); + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} + +/** + @brief Appends additional data to a previous CRC calculation using a lookup table. + @note This function can be used to compute multi-part CRCs. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bytes + @param[in] lookupTable CRC lookup table + @param[in] crc CRC from a previous calculation + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::Calculate(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc) +{ + const Parameters & parameters = lookupTable.GetParameters(); + + CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); + + remainder = CalculateRemainder(data, size, lookupTable, remainder); + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} + +/** + @brief Computes a CRC. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bits + @param[in] parameters CRC parameters + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Parameters & parameters) +{ + CRCType remainder = parameters.initialValue; + + // Calculate the remainder on a whole number of bytes first, then call + // a special-case function for the remaining bits. + crcpp_size wholeNumberOfBytes = size / CHAR_BIT; + if (wholeNumberOfBytes > 0) + { + remainder = CalculateRemainder(data, wholeNumberOfBytes, parameters, remainder); + } + + crcpp_size remainingNumberOfBits = size % CHAR_BIT; + if (remainingNumberOfBits != 0) + { + unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); + remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); + } + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} +/** + @brief Appends additional data to a previous CRC calculation. + @note This function can be used to compute multi-part CRCs. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bits + @param[in] parameters CRC parameters + @param[in] crc CRC from a previous calculation + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Parameters & parameters, CRCType crc) +{ + CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); + + // Calculate the remainder on a whole number of bytes first, then call + // a special-case function for the remaining bits. + crcpp_size wholeNumberOfBytes = size / CHAR_BIT; + if (wholeNumberOfBytes > 0) + { + remainder = CalculateRemainder(data, wholeNumberOfBytes, parameters, parameters.initialValue); + } + + crcpp_size remainingNumberOfBits = size % CHAR_BIT; + if (remainingNumberOfBits != 0) + { + unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); + remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); + } + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} + +/** + @brief Computes a CRC via a lookup table. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bits + @param[in] lookupTable CRC lookup table + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Table & lookupTable) +{ + const Parameters & parameters = lookupTable.GetParameters(); + + CRCType remainder = parameters.initialValue; + + // Calculate the remainder on a whole number of bytes first, then call + // a special-case function for the remaining bits. + crcpp_size wholeNumberOfBytes = size / CHAR_BIT; + if (wholeNumberOfBytes > 0) + { + remainder = CalculateRemainder(data, wholeNumberOfBytes, lookupTable, remainder); + } + + crcpp_size remainingNumberOfBits = size % CHAR_BIT; + if (remainingNumberOfBits != 0) + { + unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); + remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); + } + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} + +/** + @brief Appends additional data to a previous CRC calculation using a lookup table. + @note This function can be used to compute multi-part CRCs. + @param[in] data Data over which CRC will be computed + @param[in] size Size of the data, in bits + @param[in] lookupTable CRC lookup table + @param[in] crc CRC from a previous calculation + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC +*/ +template +inline CRCType CRC::CalculateBits(const void * data, crcpp_size size, const Table & lookupTable, CRCType crc) +{ + const Parameters & parameters = lookupTable.GetParameters(); + + CRCType remainder = UndoFinalize(crc, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); + + // Calculate the remainder on a whole number of bytes first, then call + // a special-case function for the remaining bits. + crcpp_size wholeNumberOfBytes = size / CHAR_BIT; + if (wholeNumberOfBytes > 0) + { + remainder = CalculateRemainder(data, wholeNumberOfBytes, lookupTable, parameters.initialValue); + } + + crcpp_size remainingNumberOfBits = size % CHAR_BIT; + if (remainingNumberOfBits > 0) + { + unsigned char lastByte = *(reinterpret_cast(data) + wholeNumberOfBytes); + remainder = CalculateRemainderBits(lastByte, remainingNumberOfBits, parameters, remainder); + } + + // No need to mask the remainder here; the mask will be applied in the Finalize() function. + + return Finalize(remainder, parameters.finalXOR, parameters.reflectInput != parameters.reflectOutput); +} + +/** + @brief Reflects (i.e. reverses the bits within) an integer value. + @param[in] value Value to reflect + @param[in] numBits Number of bits in the integer which will be reflected + @tparam IntegerType Integer type of the value being reflected + @return Reflected value +*/ +template +inline IntegerType CRC::Reflect(IntegerType value, crcpp_uint16 numBits) +{ + IntegerType reversedValue(0); + + for (crcpp_uint16 i = 0; i < numBits; ++i) + { + reversedValue = static_cast((reversedValue << 1) | (value & 1)); + value = static_cast(value >> 1); + } + + return reversedValue; +} + +/** + @brief Computes the final reflection and XOR of a CRC remainder. + @param[in] remainder CRC remainder to reflect and XOR + @param[in] finalXOR Final value to XOR with the remainder + @param[in] reflectOutput true to reflect each byte of the remainder before the XOR + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return Final CRC +*/ +template +inline CRCType CRC::Finalize(CRCType remainder, CRCType finalXOR, bool reflectOutput) +{ + // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) + static crcpp_constexpr CRCType BIT_MASK = (CRCType(1) << (CRCWidth - CRCType(1))) | + ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)); + + if (reflectOutput) + { + remainder = Reflect(remainder, CRCWidth); + } + + return (remainder ^ finalXOR) & BIT_MASK; +} + +/** + @brief Undoes the process of computing the final reflection and XOR of a CRC remainder. + @note This function allows for computation of multi-part CRCs + @note Calling UndoFinalize() followed by Finalize() (or vice versa) will always return the original remainder value: + + CRCType x = ...; + CRCType y = Finalize(x, finalXOR, reflectOutput); + CRCType z = UndoFinalize(y, finalXOR, reflectOutput); + assert(x == z); + + @param[in] crc Reflected and XORed CRC + @param[in] finalXOR Final value XORed with the remainder + @param[in] reflectOutput true if the remainder is to be reflected + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return Un-finalized CRC remainder +*/ +template +inline CRCType CRC::UndoFinalize(CRCType crc, CRCType finalXOR, bool reflectOutput) +{ + // For masking off the bits for the CRC (in the event that the number of bits in CRCType is larger than CRCWidth) + static crcpp_constexpr CRCType BIT_MASK = (CRCType(1) << (CRCWidth - CRCType(1))) | + ((CRCType(1) << (CRCWidth - CRCType(1))) - CRCType(1)); + + crc = (crc & BIT_MASK) ^ finalXOR; + + if (reflectOutput) + { + crc = Reflect(crc, CRCWidth); + } + + return crc; +} + +/** + @brief Computes a CRC remainder. + @param[in] data Data over which the remainder will be computed + @param[in] size Size of the data, in bytes + @param[in] parameters CRC parameters + @param[in] remainder Running CRC remainder. Can be an initial value or the result of a previous CRC remainder calculation. + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC remainder +*/ +template +inline CRCType CRC::CalculateRemainder(const void * data, crcpp_size size, const Parameters & parameters, CRCType remainder) +{ +#ifdef CRCPP_USE_CPP11 + // This static_assert is put here because this function will always be compiled in no matter what + // the template parameters are and whether or not a table lookup or bit-by-bit algorithm is used. + static_assert(::std::numeric_limits::digits >= CRCWidth, "CRCType is too small to contain a CRC of width CRCWidth."); +#else + // Catching this compile-time error is very important. Sadly, the compiler error will be very cryptic, but it's + // better than nothing. + enum { static_assert_failed_CRCType_is_too_small_to_contain_a_CRC_of_width_CRCWidth = 1 / (::std::numeric_limits::digits >= CRCWidth ? 1 : 0) }; +#endif + + const unsigned char * current = reinterpret_cast(data); + + // Slightly different implementations based on the parameters. The current implementations try to eliminate as much + // computation from the inner loop (looping over each bit) as possible. + if (parameters.reflectInput) + { + CRCType polynomial = CRC::Reflect(parameters.polynomial, CRCWidth); + while (size--) + { + remainder = static_cast(remainder ^ *current++); + + // An optimizing compiler might choose to unroll this loop. + for (crcpp_size i = 0; i < CHAR_BIT; ++i) + { +#ifdef CRCPP_BRANCHLESS + // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: + // if (remainder & 1) + // remainder = (remainder >> 1) ^ polynomial; + // else + // remainder >>= 1; + remainder = static_cast((remainder >> 1) ^ ((remainder & 1) * polynomial)); +#else + remainder = static_cast((remainder & 1) ? ((remainder >> 1) ^ polynomial) : (remainder >> 1)); +#endif + } + } + } + else if (CRCWidth >= CHAR_BIT) + { + static crcpp_constexpr CRCType CRC_WIDTH_MINUS_ONE(CRCWidth - CRCType(1)); +#ifndef CRCPP_BRANCHLESS + static crcpp_constexpr CRCType CRC_HIGHEST_BIT_MASK(CRCType(1) << CRC_WIDTH_MINUS_ONE); +#endif + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CRCWidth >= CHAR_BIT) ? static_cast(CRCWidth - CHAR_BIT) : 0); + + while (size--) + { + remainder = static_cast(remainder ^ (static_cast(*current++) << SHIFT)); + + // An optimizing compiler might choose to unroll this loop. + for (crcpp_size i = 0; i < CHAR_BIT; ++i) + { +#ifdef CRCPP_BRANCHLESS + // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: + // if (remainder & CRC_HIGHEST_BIT_MASK) + // remainder = (remainder << 1) ^ parameters.polynomial; + // else + // remainder <<= 1; + remainder = static_cast((remainder << 1) ^ (((remainder >> CRC_WIDTH_MINUS_ONE) & 1) * parameters.polynomial)); +#else + remainder = static_cast((remainder & CRC_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ parameters.polynomial) : (remainder << 1)); +#endif + } + } + } + else + { + static crcpp_constexpr CRCType CHAR_BIT_MINUS_ONE(CHAR_BIT - 1); +#ifndef CRCPP_BRANCHLESS + static crcpp_constexpr CRCType CHAR_BIT_HIGHEST_BIT_MASK(CRCType(1) << CHAR_BIT_MINUS_ONE); +#endif + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); + + CRCType polynomial = static_cast(parameters.polynomial << SHIFT); + remainder = static_cast(remainder << SHIFT); + + while (size--) + { + remainder = static_cast(remainder ^ *current++); + + // An optimizing compiler might choose to unroll this loop. + for (crcpp_size i = 0; i < CHAR_BIT; ++i) + { +#ifdef CRCPP_BRANCHLESS + // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: + // if (remainder & CHAR_BIT_HIGHEST_BIT_MASK) + // remainder = (remainder << 1) ^ polynomial; + // else + // remainder <<= 1; + remainder = static_cast((remainder << 1) ^ (((remainder >> CHAR_BIT_MINUS_ONE) & 1) * polynomial)); +#else + remainder = static_cast((remainder & CHAR_BIT_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ polynomial) : (remainder << 1)); +#endif + } + } + + remainder = static_cast(remainder >> SHIFT); + } + + return remainder; +} + +/** + @brief Computes a CRC remainder using lookup table. + @param[in] data Data over which the remainder will be computed + @param[in] size Size of the data, in bytes + @param[in] lookupTable CRC lookup table + @param[in] remainder Running CRC remainder. Can be an initial value or the result of a previous CRC remainder calculation. + @tparam CRCType Integer type for storing the CRC result + @tparam CRCWidth Number of bits in the CRC + @return CRC remainder +*/ +template +inline CRCType CRC::CalculateRemainder(const void * data, crcpp_size size, const Table & lookupTable, CRCType remainder) +{ + const unsigned char * current = reinterpret_cast(data); + + if (lookupTable.GetParameters().reflectInput) + { + while (size--) + remainder = static_cast((remainder >> CHAR_BIT) ^ lookupTable[static_cast(remainder ^ *current++)]); + } + else if (CRCWidth >= CHAR_BIT) + { + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CRCWidth >= CHAR_BIT) ? static_cast(CRCWidth - CHAR_BIT) : 0); + + while (size--) + { + remainder = static_cast((remainder << CHAR_BIT) ^ lookupTable[static_cast((remainder >> SHIFT) ^ *current++)]); + } + } + else + { + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); + + remainder = static_cast(remainder << SHIFT); + + while (size--) + { + // Note: no need to mask here since remainder is guaranteed to fit in a single byte. + remainder = lookupTable[static_cast(remainder ^ *current++)]; + } + + remainder = static_cast(remainder >> SHIFT); + } + + return remainder; +} + +template +inline CRCType CRC::CalculateRemainderBits(unsigned char byte, crcpp_size numBits, const Parameters & parameters, CRCType remainder) +{ + // Slightly different implementations based on the parameters. The current implementations try to eliminate as much + // computation from the inner loop (looping over each bit) as possible. + if (parameters.reflectInput) + { + CRCType polynomial = CRC::Reflect(parameters.polynomial, CRCWidth); + remainder = static_cast(remainder ^ byte); + + // An optimizing compiler might choose to unroll this loop. + for (crcpp_size i = 0; i < numBits; ++i) + { +#ifdef CRCPP_BRANCHLESS + // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: + // if (remainder & 1) + // remainder = (remainder >> 1) ^ polynomial; + // else + // remainder >>= 1; + remainder = static_cast((remainder >> 1) ^ ((remainder & 1) * polynomial)); +#else + remainder = static_cast((remainder & 1) ? ((remainder >> 1) ^ polynomial) : (remainder >> 1)); +#endif + } + } + else if (CRCWidth >= CHAR_BIT) + { + static crcpp_constexpr CRCType CRC_WIDTH_MINUS_ONE(CRCWidth - CRCType(1)); +#ifndef CRCPP_BRANCHLESS + static crcpp_constexpr CRCType CRC_HIGHEST_BIT_MASK(CRCType(1) << CRC_WIDTH_MINUS_ONE); +#endif + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CRCWidth >= CHAR_BIT) ? static_cast(CRCWidth - CHAR_BIT) : 0); + + remainder = static_cast(remainder ^ (static_cast(byte) << SHIFT)); + + // An optimizing compiler might choose to unroll this loop. + for (crcpp_size i = 0; i < numBits; ++i) + { +#ifdef CRCPP_BRANCHLESS + // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: + // if (remainder & CRC_HIGHEST_BIT_MASK) + // remainder = (remainder << 1) ^ parameters.polynomial; + // else + // remainder <<= 1; + remainder = static_cast((remainder << 1) ^ (((remainder >> CRC_WIDTH_MINUS_ONE) & 1) * parameters.polynomial)); +#else + remainder = static_cast((remainder & CRC_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ parameters.polynomial) : (remainder << 1)); +#endif + } + } + else + { + static crcpp_constexpr CRCType CHAR_BIT_MINUS_ONE(CHAR_BIT - 1); +#ifndef CRCPP_BRANCHLESS + static crcpp_constexpr CRCType CHAR_BIT_HIGHEST_BIT_MASK(CRCType(1) << CHAR_BIT_MINUS_ONE); +#endif + // The conditional expression is used to avoid a -Wshift-count-overflow warning. + static crcpp_constexpr CRCType SHIFT((CHAR_BIT >= CRCWidth) ? static_cast(CHAR_BIT - CRCWidth) : 0); + + CRCType polynomial = static_cast(parameters.polynomial << SHIFT); + remainder = static_cast((remainder << SHIFT) ^ byte); + + // An optimizing compiler might choose to unroll this loop. + for (crcpp_size i = 0; i < numBits; ++i) + { +#ifdef CRCPP_BRANCHLESS + // Clever way to avoid a branch at the expense of a multiplication. This code is equivalent to the following: + // if (remainder & CHAR_BIT_HIGHEST_BIT_MASK) + // remainder = (remainder << 1) ^ polynomial; + // else + // remainder <<= 1; + remainder = static_cast((remainder << 1) ^ (((remainder >> CHAR_BIT_MINUS_ONE) & 1) * polynomial)); +#else + remainder = static_cast((remainder & CHAR_BIT_HIGHEST_BIT_MASK) ? ((remainder << 1) ^ polynomial) : (remainder << 1)); +#endif + } + + remainder = static_cast(remainder >> SHIFT); + } + + return remainder; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-4 ITU. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-4 ITU has the following parameters and check value: + - polynomial = 0x3 + - initial value = 0x0 + - final XOR = 0x0 + - reflect input = true + - reflect output = true + - check value = 0x7 + @return CRC-4 ITU parameters +*/ +inline const CRC::Parameters & CRC::CRC_4_ITU() +{ + static const Parameters parameters = { 0x3, 0x0, 0x0, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-5 EPC. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-5 EPC has the following parameters and check value: + - polynomial = 0x09 + - initial value = 0x09 + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0x00 + @return CRC-5 EPC parameters +*/ +inline const CRC::Parameters & CRC::CRC_5_EPC() +{ + static const Parameters parameters = { 0x09, 0x09, 0x00, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-5 ITU. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-5 ITU has the following parameters and check value: + - polynomial = 0x15 + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = true + - reflect output = true + - check value = 0x07 + @return CRC-5 ITU parameters +*/ +inline const CRC::Parameters & CRC::CRC_5_ITU() +{ + static const Parameters parameters = { 0x15, 0x00, 0x00, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-5 USB. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-5 USB has the following parameters and check value: + - polynomial = 0x05 + - initial value = 0x1F + - final XOR = 0x1F + - reflect input = true + - reflect output = true + - check value = 0x19 + @return CRC-5 USB parameters +*/ +inline const CRC::Parameters & CRC::CRC_5_USB() +{ + static const Parameters parameters = { 0x05, 0x1F, 0x1F, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-6 CDMA2000-A. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-6 CDMA2000-A has the following parameters and check value: + - polynomial = 0x27 + - initial value = 0x3F + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0x0D + @return CRC-6 CDMA2000-A parameters +*/ +inline const CRC::Parameters & CRC::CRC_6_CDMA2000A() +{ + static const Parameters parameters = { 0x27, 0x3F, 0x00, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-6 CDMA2000-B. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-6 CDMA2000-A has the following parameters and check value: + - polynomial = 0x07 + - initial value = 0x3F + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0x3B + @return CRC-6 CDMA2000-B parameters +*/ +inline const CRC::Parameters & CRC::CRC_6_CDMA2000B() +{ + static const Parameters parameters = { 0x07, 0x3F, 0x00, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-6 ITU. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-6 ITU has the following parameters and check value: + - polynomial = 0x03 + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = true + - reflect output = true + - check value = 0x06 + @return CRC-6 ITU parameters +*/ +inline const CRC::Parameters & CRC::CRC_6_ITU() +{ + static const Parameters parameters = { 0x03, 0x00, 0x00, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-6 NR. + @note The parameters are static and are delayed-constructed to reduce memory + footprint. + @note CRC-6 NR has the following parameters and check value: + - polynomial = 0x21 + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0x15 + @return CRC-6 NR parameters +*/ +inline const CRC::Parameters & CRC::CRC_6_NR() +{ + static const Parameters parameters = { 0x21, 0x00, 0x00, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-7 JEDEC. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-7 JEDEC has the following parameters and check value: + - polynomial = 0x09 + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0x75 + @return CRC-7 JEDEC parameters +*/ +inline const CRC::Parameters & CRC::CRC_7() +{ + static const Parameters parameters = { 0x09, 0x00, 0x00, false, false }; + return parameters; +} +#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + +/** + @brief Returns a set of parameters for CRC-8 SMBus. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-8 SMBus has the following parameters and check value: + - polynomial = 0x07 + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0xF4 + @return CRC-8 SMBus parameters +*/ +inline const CRC::Parameters & CRC::CRC_8() +{ + static const Parameters parameters = { 0x07, 0x00, 0x00, false, false }; + return parameters; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-8 EBU (aka CRC-8 AES). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-8 EBU has the following parameters and check value: + - polynomial = 0x1D + - initial value = 0xFF + - final XOR = 0x00 + - reflect input = true + - reflect output = true + - check value = 0x97 + @return CRC-8 EBU parameters +*/ +inline const CRC::Parameters & CRC::CRC_8_EBU() +{ + static const Parameters parameters = { 0x1D, 0xFF, 0x00, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-8 MAXIM (aka CRC-8 DOW-CRC). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-8 MAXIM has the following parameters and check value: + - polynomial = 0x31 + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = true + - reflect output = true + - check value = 0xA1 + @return CRC-8 MAXIM parameters +*/ +inline const CRC::Parameters & CRC::CRC_8_MAXIM() +{ + static const Parameters parameters = { 0x31, 0x00, 0x00, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-8 WCDMA. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-8 WCDMA has the following parameters and check value: + - polynomial = 0x9B + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = true + - reflect output = true + - check value = 0x25 + @return CRC-8 WCDMA parameters +*/ +inline const CRC::Parameters & CRC::CRC_8_WCDMA() +{ + static const Parameters parameters = { 0x9B, 0x00, 0x00, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-8 LTE. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-8 LTE has the following parameters and check value: + - polynomial = 0x9B + - initial value = 0x00 + - final XOR = 0x00 + - reflect input = false + - reflect output = false + - check value = 0xEA + @return CRC-8 LTE parameters +*/ +inline const CRC::Parameters & CRC::CRC_8_LTE() +{ + static const Parameters parameters = { 0x9B, 0x00, 0x00, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-10 ITU. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-10 ITU has the following parameters and check value: + - polynomial = 0x233 + - initial value = 0x000 + - final XOR = 0x000 + - reflect input = false + - reflect output = false + - check value = 0x199 + @return CRC-10 ITU parameters +*/ +inline const CRC::Parameters & CRC::CRC_10() +{ + static const Parameters parameters = { 0x233, 0x000, 0x000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-10 CDMA2000. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-10 CDMA2000 has the following parameters and check value: + - polynomial = 0x3D9 + - initial value = 0x3FF + - final XOR = 0x000 + - reflect input = false + - reflect output = false + - check value = 0x233 + @return CRC-10 CDMA2000 parameters +*/ +inline const CRC::Parameters & CRC::CRC_10_CDMA2000() +{ + static const Parameters parameters = { 0x3D9, 0x3FF, 0x000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-11 FlexRay. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-11 FlexRay has the following parameters and check value: + - polynomial = 0x385 + - initial value = 0x01A + - final XOR = 0x000 + - reflect input = false + - reflect output = false + - check value = 0x5A3 + @return CRC-11 FlexRay parameters +*/ +inline const CRC::Parameters & CRC::CRC_11() +{ + static const Parameters parameters = { 0x385, 0x01A, 0x000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-11 NR. + @note The parameters are static and are delayed-constructed to reduce memory + footprint. + @note CRC-11 NR has the following parameters and check value: + - polynomial = 0x621 + - initial value = 0x000 + - final XOR = 0x000 + - reflect input = false + - reflect output = false + - check value = 0x5CA + @return CRC-11 NR parameters +*/ +inline const CRC::Parameters & CRC::CRC_11_NR() +{ + static const Parameters parameters = { 0x621, 0x000, 0x000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-12 CDMA2000. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-12 CDMA2000 has the following parameters and check value: + - polynomial = 0xF13 + - initial value = 0xFFF + - final XOR = 0x000 + - reflect input = false + - reflect output = false + - check value = 0xD4D + @return CRC-12 CDMA2000 parameters +*/ +inline const CRC::Parameters & CRC::CRC_12_CDMA2000() +{ + static const Parameters parameters = { 0xF13, 0xFFF, 0x000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-12 DECT (aka CRC-12 X-CRC). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-12 DECT has the following parameters and check value: + - polynomial = 0x80F + - initial value = 0x000 + - final XOR = 0x000 + - reflect input = false + - reflect output = false + - check value = 0xF5B + @return CRC-12 DECT parameters +*/ +inline const CRC::Parameters & CRC::CRC_12_DECT() +{ + static const Parameters parameters = { 0x80F, 0x000, 0x000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-12 UMTS (aka CRC-12 3GPP). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-12 UMTS has the following parameters and check value: + - polynomial = 0x80F + - initial value = 0x000 + - final XOR = 0x000 + - reflect input = false + - reflect output = true + - check value = 0xDAF + @return CRC-12 UMTS parameters +*/ +inline const CRC::Parameters & CRC::CRC_12_UMTS() +{ + static const Parameters parameters = { 0x80F, 0x000, 0x000, false, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-13 BBC. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-13 BBC has the following parameters and check value: + - polynomial = 0x1CF5 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0x04FA + @return CRC-13 BBC parameters +*/ +inline const CRC::Parameters & CRC::CRC_13_BBC() +{ + static const Parameters parameters = { 0x1CF5, 0x0000, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-15 CAN. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-15 CAN has the following parameters and check value: + - polynomial = 0x4599 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0x059E + @return CRC-15 CAN parameters +*/ +inline const CRC::Parameters & CRC::CRC_15() +{ + static const Parameters parameters = { 0x4599, 0x0000, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-15 MPT1327. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-15 MPT1327 has the following parameters and check value: + - polynomial = 0x6815 + - initial value = 0x0000 + - final XOR = 0x0001 + - reflect input = false + - reflect output = false + - check value = 0x2566 + @return CRC-15 MPT1327 parameters +*/ +inline const CRC::Parameters & CRC::CRC_15_MPT1327() +{ + static const Parameters parameters = { 0x6815, 0x0000, 0x0001, false, false }; + return parameters; +} +#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + +/** + @brief Returns a set of parameters for CRC-16 ARC (aka CRC-16 IBM, CRC-16 LHA). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 ARC has the following parameters and check value: + - polynomial = 0x8005 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = true + - reflect output = true + - check value = 0xBB3D + @return CRC-16 ARC parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_ARC() +{ + static const Parameters parameters = { 0x8005, 0x0000, 0x0000, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 BUYPASS (aka CRC-16 VERIFONE, CRC-16 UMTS). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 BUYPASS has the following parameters and check value: + - polynomial = 0x8005 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0xFEE8 + @return CRC-16 BUYPASS parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_BUYPASS() +{ + static const Parameters parameters = { 0x8005, 0x0000, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 CCITT FALSE. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 CCITT FALSE has the following parameters and check value: + - polynomial = 0x1021 + - initial value = 0xFFFF + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0x29B1 + @return CRC-16 CCITT FALSE parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_CCITTFALSE() +{ + static const Parameters parameters = { 0x1021, 0xFFFF, 0x0000, false, false }; + return parameters; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-16 CDMA2000. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 CDMA2000 has the following parameters and check value: + - polynomial = 0xC867 + - initial value = 0xFFFF + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0x4C06 + @return CRC-16 CDMA2000 parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_CDMA2000() +{ + static const Parameters parameters = { 0xC867, 0xFFFF, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 CMS. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 CMS has the following parameters and check value: + - polynomial = 0x8005 + - initial value = 0xFFFF + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0xAEE7 + @return CRC-16 CMS parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_CMS() +{ + static const Parameters parameters = { 0x8005, 0xFFFF, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 DECT-R (aka CRC-16 R-CRC). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 DECT-R has the following parameters and check value: + - polynomial = 0x0589 + - initial value = 0x0000 + - final XOR = 0x0001 + - reflect input = false + - reflect output = false + - check value = 0x007E + @return CRC-16 DECT-R parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_DECTR() +{ + static const Parameters parameters = { 0x0589, 0x0000, 0x0001, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 DECT-X (aka CRC-16 X-CRC). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 DECT-X has the following parameters and check value: + - polynomial = 0x0589 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0x007F + @return CRC-16 DECT-X parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_DECTX() +{ + static const Parameters parameters = { 0x0589, 0x0000, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 DNP. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 DNP has the following parameters and check value: + - polynomial = 0x3D65 + - initial value = 0x0000 + - final XOR = 0xFFFF + - reflect input = true + - reflect output = true + - check value = 0xEA82 + @return CRC-16 DNP parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_DNP() +{ + static const Parameters parameters = { 0x3D65, 0x0000, 0xFFFF, true, true }; + return parameters; +} +#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + +/** + @brief Returns a set of parameters for CRC-16 GENIBUS (aka CRC-16 EPC, CRC-16 I-CODE, CRC-16 DARC). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 GENIBUS has the following parameters and check value: + - polynomial = 0x1021 + - initial value = 0xFFFF + - final XOR = 0xFFFF + - reflect input = false + - reflect output = false + - check value = 0xD64E + @return CRC-16 GENIBUS parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_GENIBUS() +{ + static const Parameters parameters = { 0x1021, 0xFFFF, 0xFFFF, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 KERMIT (aka CRC-16 CCITT, CRC-16 CCITT-TRUE). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 KERMIT has the following parameters and check value: + - polynomial = 0x1021 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = true + - reflect output = true + - check value = 0x2189 + @return CRC-16 KERMIT parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_KERMIT() +{ + static const Parameters parameters = { 0x1021, 0x0000, 0x0000, true, true }; + return parameters; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-16 MAXIM. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 MAXIM has the following parameters and check value: + - polynomial = 0x8005 + - initial value = 0x0000 + - final XOR = 0xFFFF + - reflect input = true + - reflect output = true + - check value = 0x44C2 + @return CRC-16 MAXIM parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_MAXIM() +{ + static const Parameters parameters = { 0x8005, 0x0000, 0xFFFF, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 MODBUS. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 MODBUS has the following parameters and check value: + - polynomial = 0x8005 + - initial value = 0xFFFF + - final XOR = 0x0000 + - reflect input = true + - reflect output = true + - check value = 0x4B37 + @return CRC-16 MODBUS parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_MODBUS() +{ + static const Parameters parameters = { 0x8005, 0xFFFF, 0x0000, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 T10-DIF. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 T10-DIF has the following parameters and check value: + - polynomial = 0x8BB7 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0xD0DB + @return CRC-16 T10-DIF parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_T10DIF() +{ + static const Parameters parameters = { 0x8BB7, 0x0000, 0x0000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 USB. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 USB has the following parameters and check value: + - polynomial = 0x8005 + - initial value = 0xFFFF + - final XOR = 0xFFFF + - reflect input = true + - reflect output = true + - check value = 0xB4C8 + @return CRC-16 USB parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_USB() +{ + static const Parameters parameters = { 0x8005, 0xFFFF, 0xFFFF, true, true }; + return parameters; +} + +#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + +/** + @brief Returns a set of parameters for CRC-16 X-25 (aka CRC-16 IBM-SDLC, CRC-16 ISO-HDLC, CRC-16 B). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 X-25 has the following parameters and check value: + - polynomial = 0x1021 + - initial value = 0xFFFF + - final XOR = 0xFFFF + - reflect input = true + - reflect output = true + - check value = 0x906E + @return CRC-16 X-25 parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_X25() +{ + static const Parameters parameters = { 0x1021, 0xFFFF, 0xFFFF, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-16 XMODEM (aka CRC-16 ZMODEM, CRC-16 ACORN, CRC-16 LTE). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-16 XMODEM has the following parameters and check value: + - polynomial = 0x1021 + - initial value = 0x0000 + - final XOR = 0x0000 + - reflect input = false + - reflect output = false + - check value = 0x31C3 + @return CRC-16 XMODEM parameters +*/ +inline const CRC::Parameters & CRC::CRC_16_XMODEM() +{ + static const Parameters parameters = { 0x1021, 0x0000, 0x0000, false, false }; + return parameters; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-17 CAN. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-17 CAN has the following parameters and check value: + - polynomial = 0x1685B + - initial value = 0x00000 + - final XOR = 0x00000 + - reflect input = false + - reflect output = false + - check value = 0x04F03 + @return CRC-17 CAN parameters +*/ +inline const CRC::Parameters & CRC::CRC_17_CAN() +{ + static const Parameters parameters = { 0x1685B, 0x00000, 0x00000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-21 CAN. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-21 CAN has the following parameters and check value: + - polynomial = 0x102899 + - initial value = 0x000000 + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0x0ED841 + @return CRC-21 CAN parameters +*/ +inline const CRC::Parameters & CRC::CRC_21_CAN() +{ + static const Parameters parameters = { 0x102899, 0x000000, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-24 OPENPGP. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-24 OPENPGP has the following parameters and check value: + - polynomial = 0x864CFB + - initial value = 0xB704CE + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0x21CF02 + @return CRC-24 OPENPGP parameters +*/ +inline const CRC::Parameters & CRC::CRC_24() +{ + static const Parameters parameters = { 0x864CFB, 0xB704CE, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-24 FlexRay-A. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-24 FlexRay-A has the following parameters and check value: + - polynomial = 0x5D6DCB + - initial value = 0xFEDCBA + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0x7979BD + @return CRC-24 FlexRay-A parameters +*/ +inline const CRC::Parameters & CRC::CRC_24_FLEXRAYA() +{ + static const Parameters parameters = { 0x5D6DCB, 0xFEDCBA, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-24 FlexRay-B. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-24 FlexRay-B has the following parameters and check value: + - polynomial = 0x5D6DCB + - initial value = 0xABCDEF + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0x1F23B8 + @return CRC-24 FlexRay-B parameters +*/ +inline const CRC::Parameters & CRC::CRC_24_FLEXRAYB() +{ + static const Parameters parameters = { 0x5D6DCB, 0xABCDEF, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-24 LTE-A/NR-A. + @note The parameters are static and are delayed-constructed to reduce memory + footprint. + @note CRC-24 LTE-A has the following parameters and check value: + - polynomial = 0x864CFB + - initial value = 0x000000 + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0xCDE703 + @return CRC-24 LTE-A parameters +*/ +inline const CRC::Parameters & CRC::CRC_24_LTEA() +{ + static const Parameters parameters = { 0x864CFB, 0x000000, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-24 LTE-B/NR-B. + @note The parameters are static and are delayed-constructed to reduce memory + footprint. + @note CRC-24 LTE-B has the following parameters and check value: + - polynomial = 0x800063 + - initial value = 0x000000 + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0x23EF52 + @return CRC-24 LTE-B parameters +*/ +inline const CRC::Parameters & CRC::CRC_24_LTEB() +{ + static const Parameters parameters = { 0x800063, 0x000000, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-24 NR-C. + @note The parameters are static and are delayed-constructed to reduce memory + footprint. + @note CRC-24 NR-C has the following parameters and check value: + - polynomial = 0xB2B117 + - initial value = 0x000000 + - final XOR = 0x000000 + - reflect input = false + - reflect output = false + - check value = 0xF48279 + @return CRC-24 NR-C parameters +*/ +inline const CRC::Parameters & CRC::CRC_24_NRC() +{ + static const Parameters parameters = { 0xB2B117, 0x000000, 0x000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-30 CDMA. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-30 CDMA has the following parameters and check value: + - polynomial = 0x2030B9C7 + - initial value = 0x3FFFFFFF + - final XOR = 0x00000000 + - reflect input = false + - reflect output = false + - check value = 0x3B3CB540 + @return CRC-30 CDMA parameters +*/ +inline const CRC::Parameters & CRC::CRC_30() +{ + static const Parameters parameters = { 0x2030B9C7, 0x3FFFFFFF, 0x00000000, false, false }; + return parameters; +} +#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + +/** + @brief Returns a set of parameters for CRC-32 (aka CRC-32 ADCCP, CRC-32 PKZip). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-32 has the following parameters and check value: + - polynomial = 0x04C11DB7 + - initial value = 0xFFFFFFFF + - final XOR = 0xFFFFFFFF + - reflect input = true + - reflect output = true + - check value = 0xCBF43926 + @return CRC-32 parameters +*/ +inline const CRC::Parameters & CRC::CRC_32() +{ + static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-32 BZIP2 (aka CRC-32 AAL5, CRC-32 DECT-B, CRC-32 B-CRC). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-32 BZIP2 has the following parameters and check value: + - polynomial = 0x04C11DB7 + - initial value = 0xFFFFFFFF + - final XOR = 0xFFFFFFFF + - reflect input = false + - reflect output = false + - check value = 0xFC891918 + @return CRC-32 BZIP2 parameters +*/ +inline const CRC::Parameters & CRC::CRC_32_BZIP2() +{ + static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0xFFFFFFFF, false, false }; + return parameters; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-32 C (aka CRC-32 ISCSI, CRC-32 Castagnoli, CRC-32 Interlaken). + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-32 C has the following parameters and check value: + - polynomial = 0x1EDC6F41 + - initial value = 0xFFFFFFFF + - final XOR = 0xFFFFFFFF + - reflect input = true + - reflect output = true + - check value = 0xE3069283 + @return CRC-32 C parameters +*/ +inline const CRC::Parameters & CRC::CRC_32_C() +{ + static const Parameters parameters = { 0x1EDC6F41, 0xFFFFFFFF, 0xFFFFFFFF, true, true }; + return parameters; +} +#endif + +/** + @brief Returns a set of parameters for CRC-32 MPEG-2. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-32 MPEG-2 has the following parameters and check value: + - polynomial = 0x04C11DB7 + - initial value = 0xFFFFFFFF + - final XOR = 0x00000000 + - reflect input = false + - reflect output = false + - check value = 0x0376E6E7 + @return CRC-32 MPEG-2 parameters +*/ +inline const CRC::Parameters & CRC::CRC_32_MPEG2() +{ + static const Parameters parameters = { 0x04C11DB7, 0xFFFFFFFF, 0x00000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-32 POSIX. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-32 POSIX has the following parameters and check value: + - polynomial = 0x04C11DB7 + - initial value = 0x00000000 + - final XOR = 0xFFFFFFFF + - reflect input = false + - reflect output = false + - check value = 0x765E7680 + @return CRC-32 POSIX parameters +*/ +inline const CRC::Parameters & CRC::CRC_32_POSIX() +{ + static const Parameters parameters = { 0x04C11DB7, 0x00000000, 0xFFFFFFFF, false, false }; + return parameters; +} + +#ifdef CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS +/** + @brief Returns a set of parameters for CRC-32 Q. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-32 Q has the following parameters and check value: + - polynomial = 0x814141AB + - initial value = 0x00000000 + - final XOR = 0x00000000 + - reflect input = false + - reflect output = false + - check value = 0x3010BF7F + @return CRC-32 Q parameters +*/ +inline const CRC::Parameters & CRC::CRC_32_Q() +{ + static const Parameters parameters = { 0x814141AB, 0x00000000, 0x00000000, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-40 GSM. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-40 GSM has the following parameters and check value: + - polynomial = 0x0004820009 + - initial value = 0x0000000000 + - final XOR = 0xFFFFFFFFFF + - reflect input = false + - reflect output = false + - check value = 0xD4164FC646 + @return CRC-40 GSM parameters +*/ +inline const CRC::Parameters & CRC::CRC_40_GSM() +{ + static const Parameters parameters = { 0x0004820009, 0x0000000000, 0xFFFFFFFFFF, false, false }; + return parameters; +} + +/** + @brief Returns a set of parameters for CRC-64 ECMA. + @note The parameters are static and are delayed-constructed to reduce memory footprint. + @note CRC-64 ECMA has the following parameters and check value: + - polynomial = 0x42F0E1EBA9EA3693 + - initial value = 0x0000000000000000 + - final XOR = 0x0000000000000000 + - reflect input = false + - reflect output = false + - check value = 0x6C40DF5F0B497347 + @return CRC-64 ECMA parameters +*/ +inline const CRC::Parameters & CRC::CRC_64() +{ + static const Parameters parameters = { 0x42F0E1EBA9EA3693, 0x0000000000000000, 0x0000000000000000, false, false }; + return parameters; +} +#endif // CRCPP_INCLUDE_ESOTERIC_CRC_DEFINITIONS + +#ifdef CRCPP_USE_NAMESPACE +} +#endif + +#endif // CRCPP_CRC_H_ diff --git a/include/discord/discord_register.h b/include/discord/discord_register.h new file mode 100644 index 0000000..16fb42f --- /dev/null +++ b/include/discord/discord_register.h @@ -0,0 +1,26 @@ +#pragma once + +#if defined(DISCORD_DYNAMIC_LIB) +#if defined(_WIN32) +#if defined(DISCORD_BUILDING_SDK) +#define DISCORD_EXPORT __declspec(dllexport) +#else +#define DISCORD_EXPORT __declspec(dllimport) +#endif +#else +#define DISCORD_EXPORT __attribute__((visibility("default"))) +#endif +#else +#define DISCORD_EXPORT +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +DISCORD_EXPORT void Discord_Register(const char* applicationId, const char* command); +DISCORD_EXPORT void Discord_RegisterSteamGame(const char* applicationId, const char* steamId); + +#ifdef __cplusplus +} +#endif diff --git a/include/discord/discord_rpc.h b/include/discord/discord_rpc.h new file mode 100644 index 0000000..3e1441e --- /dev/null +++ b/include/discord/discord_rpc.h @@ -0,0 +1,87 @@ +#pragma once +#include + +// clang-format off + +#if defined(DISCORD_DYNAMIC_LIB) +# if defined(_WIN32) +# if defined(DISCORD_BUILDING_SDK) +# define DISCORD_EXPORT __declspec(dllexport) +# else +# define DISCORD_EXPORT __declspec(dllimport) +# endif +# else +# define DISCORD_EXPORT __attribute__((visibility("default"))) +# endif +#else +# define DISCORD_EXPORT +#endif + +// clang-format on + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct DiscordRichPresence { + const char* state; /* max 128 bytes */ + const char* details; /* max 128 bytes */ + int64_t startTimestamp; + int64_t endTimestamp; + const char* largeImageKey; /* max 32 bytes */ + const char* largeImageText; /* max 128 bytes */ + const char* smallImageKey; /* max 32 bytes */ + const char* smallImageText; /* max 128 bytes */ + const char* partyId; /* max 128 bytes */ + int partySize; + int partyMax; + const char* matchSecret; /* max 128 bytes */ + const char* joinSecret; /* max 128 bytes */ + const char* spectateSecret; /* max 128 bytes */ + int8_t instance; +} DiscordRichPresence; + +typedef struct DiscordUser { + const char* userId; + const char* username; + const char* discriminator; + const char* avatar; +} DiscordUser; + +typedef struct DiscordEventHandlers { + void (*ready)(const DiscordUser* request); + void (*disconnected)(int errorCode, const char* message); + void (*errored)(int errorCode, const char* message); + void (*joinGame)(const char* joinSecret); + void (*spectateGame)(const char* spectateSecret); + void (*joinRequest)(const DiscordUser* request); +} DiscordEventHandlers; + +#define DISCORD_REPLY_NO 0 +#define DISCORD_REPLY_YES 1 +#define DISCORD_REPLY_IGNORE 2 + +DISCORD_EXPORT void Discord_Initialize(const char* applicationId, + DiscordEventHandlers* handlers, + int autoRegister, + const char* optionalSteamId); +DISCORD_EXPORT void Discord_Shutdown(void); + +/* checks for incoming messages, dispatches callbacks */ +DISCORD_EXPORT void Discord_RunCallbacks(void); + +/* If you disable the lib starting its own io thread, you'll need to call this from your own */ +#ifdef DISCORD_DISABLE_IO_THREAD +DISCORD_EXPORT void Discord_UpdateConnection(void); +#endif + +DISCORD_EXPORT void Discord_UpdatePresence(const DiscordRichPresence* presence); +DISCORD_EXPORT void Discord_ClearPresence(void); + +DISCORD_EXPORT void Discord_Respond(const char* userid, /* DISCORD_REPLY_ */ int reply); + +DISCORD_EXPORT void Discord_UpdateHandlers(DiscordEventHandlers* handlers); + +#ifdef __cplusplus +} /* extern "C" */ +#endif diff --git a/include/lua/lapi.h b/include/lua/lapi.h new file mode 100644 index 0000000..9e99cc4 --- /dev/null +++ b/include/lua/lapi.h @@ -0,0 +1,49 @@ +/* +** $Id: lapi.h $ +** Auxiliary functions from Lua API +** See Copyright Notice in lua.h +*/ + +#ifndef lapi_h +#define lapi_h + + +#include "llimits.h" +#include "lstate.h" + + +/* Increments 'L->top', checking for stack overflows */ +#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \ + "stack overflow");} + + +/* +** If a call returns too many multiple returns, the callee may not have +** stack space to accommodate all results. In this case, this macro +** increases its stack space ('L->ci->top'). +*/ +#define adjustresults(L,nres) \ + { if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; } + + +/* Ensure the stack has at least 'n' elements */ +#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \ + "not enough elements in the stack") + + +/* +** To reduce the overhead of returning from C functions, the presence of +** to-be-closed variables in these functions is coded in the CallInfo's +** field 'nresults', in a way that functions with no to-be-closed variables +** with zero, one, or "all" wanted results have no overhead. Functions +** with other number of wanted results, as well as functions with +** variables to be closed, have an extra check. +*/ + +#define hastocloseCfunc(n) ((n) < LUA_MULTRET) + +/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */ +#define codeNresults(n) (-(n) - 3) +#define decodeNresults(n) (-(n) - 3) + +#endif diff --git a/include/lua/lauxlib.h b/include/lua/lauxlib.h new file mode 100644 index 0000000..72f70e7 --- /dev/null +++ b/include/lua/lauxlib.h @@ -0,0 +1,293 @@ +/* +** $Id: lauxlib.h $ +** Auxiliary functions for building Lua libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lauxlib_h +#define lauxlib_h + + +#include +#include + +#include "luaconf.h" +#include "lua.h" + + +/* global table */ +#define LUA_GNAME "_G" + + +typedef struct luaL_Buffer luaL_Buffer; + + +/* extra error code for 'luaL_loadfilex' */ +#define LUA_ERRFILE (LUA_ERRERR+1) + + +/* key, in the registry, for table of loaded modules */ +#define LUA_LOADED_TABLE "_LOADED" + + +/* key, in the registry, for table of preloaded loaders */ +#define LUA_PRELOAD_TABLE "_PRELOAD" + + +typedef struct luaL_Reg { + const char *name; + lua_CFunction func; +} luaL_Reg; + + +#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number)) + +LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver, size_t sz); +#define luaL_checkversion(L) \ + luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES) + +LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); +LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); +LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); +LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg); +LUALIB_API int (luaL_typeerror) (lua_State *L, int arg, const char *tname); +LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg, + size_t *l); +LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg, + const char *def, size_t *l); +LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg); +LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def); + +LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg); +LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg, + lua_Integer def); + +LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg); +LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t); +LUALIB_API void (luaL_checkany) (lua_State *L, int arg); + +LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname); +LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname); +LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname); +LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); + +LUALIB_API void (luaL_where) (lua_State *L, int lvl); +LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...); + +LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def, + const char *const lst[]); + +LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname); +LUALIB_API int (luaL_execresult) (lua_State *L, int stat); + + +/* predefined references */ +#define LUA_NOREF (-2) +#define LUA_REFNIL (-1) + +LUALIB_API int (luaL_ref) (lua_State *L, int t); +LUALIB_API void (luaL_unref) (lua_State *L, int t, int ref); + +LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename, + const char *mode); + +#define luaL_loadfile(L,f) luaL_loadfilex(L,f,NULL) + +LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz, + const char *name, const char *mode); +LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s); + +LUALIB_API lua_State *(luaL_newstate) (void); + +LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx); + +LUALIB_API void luaL_addgsub (luaL_Buffer *b, const char *s, + const char *p, const char *r); +LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, + const char *p, const char *r); + +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + +LUALIB_API int (luaL_getsubtable) (lua_State *L, int idx, const char *fname); + +LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, + const char *msg, int level); + +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); + +/* +** =============================================================== +** some useful macros +** =============================================================== +*/ + + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) \ + (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + +#define luaL_argcheck(L, cond,arg,extramsg) \ + ((void)(luai_likely(cond) || luaL_argerror(L, (arg), (extramsg)))) + +#define luaL_argexpected(L,cond,arg,tname) \ + ((void)(luai_likely(cond) || luaL_typeerror(L, (arg), (tname)))) + +#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) +#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL)) + +#define luaL_typename(L,i) lua_typename(L, lua_type(L,(i))) + +#define luaL_dofile(L, fn) \ + (luaL_loadfile(L, fn) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_dostring(L, s) \ + (luaL_loadstring(L, s) || lua_pcall(L, 0, LUA_MULTRET, 0)) + +#define luaL_getmetatable(L,n) (lua_getfield(L, LUA_REGISTRYINDEX, (n))) + +#define luaL_opt(L,f,n,d) (lua_isnoneornil(L,(n)) ? (d) : f(L,(n))) + +#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL) + + +/* push the value used to represent failure/error */ +#define luaL_pushfail(L) lua_pushnil(L) + + +/* +** Internal assertions for in-house debugging +*/ +#if !defined(lua_assert) + +#if defined LUAI_ASSERT + #include + #define lua_assert(c) assert(c) +#else + #define lua_assert(c) ((void)0) +#endif + +#endif + + + +/* +** {====================================================== +** Generic Buffer manipulation +** ======================================================= +*/ + +struct luaL_Buffer { + char *b; /* buffer address */ + size_t size; /* buffer size */ + size_t n; /* number of characters in buffer */ + lua_State *L; + union { + LUAI_MAXALIGN; /* ensure maximum alignment for buffer */ + char b[LUAL_BUFFERSIZE]; /* initial buffer */ + } init; +}; + + +#define luaL_bufflen(bf) ((bf)->n) +#define luaL_buffaddr(bf) ((bf)->b) + + +#define luaL_addchar(B,c) \ + ((void)((B)->n < (B)->size || luaL_prepbuffsize((B), 1)), \ + ((B)->b[(B)->n++] = (c))) + +#define luaL_addsize(B,s) ((B)->n += (s)) + +#define luaL_buffsub(B,s) ((B)->n -= (s)) + +LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B); +LUALIB_API char *(luaL_prepbuffsize) (luaL_Buffer *B, size_t sz); +LUALIB_API void (luaL_addlstring) (luaL_Buffer *B, const char *s, size_t l); +LUALIB_API void (luaL_addstring) (luaL_Buffer *B, const char *s); +LUALIB_API void (luaL_addvalue) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresult) (luaL_Buffer *B); +LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz); +LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); + +#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE) + +/* }====================================================== */ + + + +/* +** {====================================================== +** File handles for IO library +** ======================================================= +*/ + +/* +** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and +** initial structure 'luaL_Stream' (it may contain other fields +** after that initial structure). +*/ + +#define LUA_FILEHANDLE "FILE*" + + +typedef struct luaL_Stream { + FILE *f; /* stream (NULL for incompletely created streams) */ + lua_CFunction closef; /* to close stream (NULL for closed streams) */ +} luaL_Stream; + +/* }====================================================== */ + +/* +** {================================================================== +** "Abstraction Layer" for basic report of messages and errors +** =================================================================== +*/ + +/* print a string */ +#if !defined(lua_writestring) +#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout) +#endif + +/* print a newline and flush the output */ +#if !defined(lua_writeline) +#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout)) +#endif + +/* print an error message */ +#if !defined(lua_writestringerror) +#define lua_writestringerror(s,p) \ + (fprintf(stderr, (s), (p)), fflush(stderr)) +#endif + +/* }================================================================== */ + + +/* +** {============================================================ +** Compatibility with deprecated conversions +** ============================================================= +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a)) +#define luaL_optunsigned(L,a,d) \ + ((lua_Unsigned)luaL_optinteger(L,a,(lua_Integer)(d))) + +#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n))) +#define luaL_optint(L,n,d) ((int)luaL_optinteger(L, (n), (d))) + +#define luaL_checklong(L,n) ((long)luaL_checkinteger(L, (n))) +#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d))) + +#endif +/* }============================================================ */ + + + +#endif + + diff --git a/include/lua/lcode.h b/include/lua/lcode.h new file mode 100644 index 0000000..3265824 --- /dev/null +++ b/include/lua/lcode.h @@ -0,0 +1,104 @@ +/* +** $Id: lcode.h $ +** Code generator for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lcode_h +#define lcode_h + +#include "llex.h" +#include "lobject.h" +#include "lopcodes.h" +#include "lparser.h" + + +/* +** Marks the end of a patch list. It is an invalid value both as an absolute +** address, and as a list link (would link an element to itself). +*/ +#define NO_JUMP (-1) + + +/* +** grep "ORDER OPR" if you change these enums (ORDER OP) +*/ +typedef enum BinOpr { + /* arithmetic operators */ + OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW, + OPR_DIV, OPR_IDIV, + /* bitwise operators */ + OPR_BAND, OPR_BOR, OPR_BXOR, + OPR_SHL, OPR_SHR, + /* string operator */ + OPR_CONCAT, + /* comparison operators */ + OPR_EQ, OPR_LT, OPR_LE, + OPR_NE, OPR_GT, OPR_GE, + /* logical operators */ + OPR_AND, OPR_OR, + OPR_NOBINOPR +} BinOpr; + + +/* true if operation is foldable (that is, it is arithmetic or bitwise) */ +#define foldbinop(op) ((op) <= OPR_SHR) + + +#define luaK_codeABC(fs,o,a,b,c) luaK_codeABCk(fs,o,a,b,c,0) + + +typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr; + + +/* get (pointer to) instruction of given 'expdesc' */ +#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info]) + + +#define luaK_setmultret(fs,e) luaK_setreturns(fs, e, LUA_MULTRET) + +#define luaK_jumpto(fs,t) luaK_patchlist(fs, luaK_jump(fs), t) + +LUAI_FUNC int luaK_code (FuncState *fs, Instruction i); +LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx); +LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx); +LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A, + int B, int C, int k); +LUAI_FUNC int luaK_isKint (expdesc *e); +LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v); +LUAI_FUNC void luaK_fixline (FuncState *fs, int line); +LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n); +LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n); +LUAI_FUNC void luaK_checkstack (FuncState *fs, int n); +LUAI_FUNC void luaK_int (FuncState *fs, int reg, lua_Integer n); +LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key); +LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k); +LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_goiffalse (FuncState *fs, expdesc *e); +LUAI_FUNC void luaK_storevar (FuncState *fs, expdesc *var, expdesc *e); +LUAI_FUNC void luaK_setreturns (FuncState *fs, expdesc *e, int nresults); +LUAI_FUNC void luaK_setoneret (FuncState *fs, expdesc *e); +LUAI_FUNC int luaK_jump (FuncState *fs); +LUAI_FUNC void luaK_ret (FuncState *fs, int first, int nret); +LUAI_FUNC void luaK_patchlist (FuncState *fs, int list, int target); +LUAI_FUNC void luaK_patchtohere (FuncState *fs, int list); +LUAI_FUNC void luaK_concat (FuncState *fs, int *l1, int l2); +LUAI_FUNC int luaK_getlabel (FuncState *fs); +LUAI_FUNC void luaK_prefix (FuncState *fs, UnOpr op, expdesc *v, int line); +LUAI_FUNC void luaK_infix (FuncState *fs, BinOpr op, expdesc *v); +LUAI_FUNC void luaK_posfix (FuncState *fs, BinOpr op, expdesc *v1, + expdesc *v2, int line); +LUAI_FUNC void luaK_settablesize (FuncState *fs, int pc, + int ra, int asize, int hsize); +LUAI_FUNC void luaK_setlist (FuncState *fs, int base, int nelems, int tostore); +LUAI_FUNC void luaK_finish (FuncState *fs); +LUAI_FUNC l_noret luaK_semerror (LexState *ls, const char *msg); + + +#endif diff --git a/include/lua/lctype.h b/include/lua/lctype.h new file mode 100644 index 0000000..864e190 --- /dev/null +++ b/include/lua/lctype.h @@ -0,0 +1,101 @@ +/* +** $Id: lctype.h $ +** 'ctype' functions for Lua +** See Copyright Notice in lua.h +*/ + +#ifndef lctype_h +#define lctype_h + +#include "lua.h" + + +/* +** WARNING: the functions defined here do not necessarily correspond +** to the similar functions in the standard C ctype.h. They are +** optimized for the specific needs of Lua. +*/ + +#if !defined(LUA_USE_CTYPE) + +#if 'A' == 65 && '0' == 48 +/* ASCII case: can use its own tables; faster and fixed */ +#define LUA_USE_CTYPE 0 +#else +/* must use standard C ctype */ +#define LUA_USE_CTYPE 1 +#endif + +#endif + + +#if !LUA_USE_CTYPE /* { */ + +#include + +#include "llimits.h" + + +#define ALPHABIT 0 +#define DIGITBIT 1 +#define PRINTBIT 2 +#define SPACEBIT 3 +#define XDIGITBIT 4 + + +#define MASK(B) (1 << (B)) + + +/* +** add 1 to char to allow index -1 (EOZ) +*/ +#define testprop(c,p) (luai_ctype_[(c)+1] & (p)) + +/* +** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_' +*/ +#define lislalpha(c) testprop(c, MASK(ALPHABIT)) +#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT))) +#define lisdigit(c) testprop(c, MASK(DIGITBIT)) +#define lisspace(c) testprop(c, MASK(SPACEBIT)) +#define lisprint(c) testprop(c, MASK(PRINTBIT)) +#define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) + + +/* +** In ASCII, this 'ltolower' is correct for alphabetic characters and +** for '.'. That is enough for Lua needs. ('check_exp' ensures that +** the character either is an upper-case letter or is unchanged by +** the transformation, which holds for lower-case letters and '.'.) +*/ +#define ltolower(c) \ + check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ + (c) | ('A' ^ 'a')) + + +/* one entry for each character and for -1 (EOZ) */ +LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) + + +#else /* }{ */ + +/* +** use standard C ctypes +*/ + +#include + + +#define lislalpha(c) (isalpha(c) || (c) == '_') +#define lislalnum(c) (isalnum(c) || (c) == '_') +#define lisdigit(c) (isdigit(c)) +#define lisspace(c) (isspace(c)) +#define lisprint(c) (isprint(c)) +#define lisxdigit(c) (isxdigit(c)) + +#define ltolower(c) (tolower(c)) + +#endif /* } */ + +#endif + diff --git a/include/lua/ldebug.h b/include/lua/ldebug.h new file mode 100644 index 0000000..974960e --- /dev/null +++ b/include/lua/ldebug.h @@ -0,0 +1,63 @@ +/* +** $Id: ldebug.h $ +** Auxiliary functions from Debug Interface module +** See Copyright Notice in lua.h +*/ + +#ifndef ldebug_h +#define ldebug_h + + +#include "lstate.h" + + +#define pcRel(pc, p) (cast_int((pc) - (p)->code) - 1) + + +/* Active Lua function (given call info) */ +#define ci_func(ci) (clLvalue(s2v((ci)->func))) + + +#define resethookcount(L) (L->hookcount = L->basehookcount) + +/* +** mark for entries in 'lineinfo' array that has absolute information in +** 'abslineinfo' array +*/ +#define ABSLINEINFO (-0x80) + + +/* +** MAXimum number of successive Instructions WiTHout ABSolute line +** information. (A power of two allows fast divisions.) +*/ +#if !defined(MAXIWTHABS) +#define MAXIWTHABS 128 +#endif + + +LUAI_FUNC int luaG_getfuncline (const Proto *f, int pc); +LUAI_FUNC const char *luaG_findlocal (lua_State *L, CallInfo *ci, int n, + StkId *pos); +LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o, + const char *opname); +LUAI_FUNC l_noret luaG_callerror (lua_State *L, const TValue *o); +LUAI_FUNC l_noret luaG_forerror (lua_State *L, const TValue *o, + const char *what); +LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_opinterror (lua_State *L, const TValue *p1, + const TValue *p2, + const char *msg); +LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1, + const TValue *p2); +LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...); +LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg, + TString *src, int line); +LUAI_FUNC l_noret luaG_errormsg (lua_State *L); +LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc); + + +#endif diff --git a/include/lua/ldo.h b/include/lua/ldo.h new file mode 100644 index 0000000..6bf0ed8 --- /dev/null +++ b/include/lua/ldo.h @@ -0,0 +1,79 @@ +/* +** $Id: ldo.h $ +** Stack and Call structure of Lua +** See Copyright Notice in lua.h +*/ + +#ifndef ldo_h +#define ldo_h + + +#include "lobject.h" +#include "lstate.h" +#include "lzio.h" + + +/* +** Macro to check stack size and grow stack if needed. Parameters +** 'pre'/'pos' allow the macro to preserve a pointer into the +** stack across reallocations, doing the work only when needed. +** It also allows the running of one GC step when the stack is +** reallocated. +** 'condmovestack' is used in heavy tests to force a stack reallocation +** at every check. +*/ +#define luaD_checkstackaux(L,n,pre,pos) \ + if (l_unlikely(L->stack_last - L->top <= (n))) \ + { pre; luaD_growstack(L, n, 1); pos; } \ + else { condmovestack(L,pre,pos); } + +/* In general, 'pre'/'pos' are empty (nothing to save) */ +#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0) + + + +#define savestack(L,p) ((char *)(p) - (char *)L->stack) +#define restorestack(L,n) ((StkId)((char *)L->stack + (n))) + + +/* macro to check stack size, preserving 'p' */ +#define checkstackGCp(L,n,p) \ + luaD_checkstackaux(L, n, \ + ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \ + luaC_checkGC(L), /* stack grow uses memory */ \ + p = restorestack(L, t__)) /* 'pos' part: restore 'p' */ + + +/* macro to check stack size and GC */ +#define checkstackGC(L,fsize) \ + luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0) + + +/* type of protected functions, to be ran by 'runprotected' */ +typedef void (*Pfunc) (lua_State *L, void *ud); + +LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop); +LUAI_FUNC int luaD_protectedparser (lua_State *L, ZIO *z, const char *name, + const char *mode); +LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, + int fTransfer, int nTransfer); +LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); +LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); +LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); +LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); +LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status); +LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u, + ptrdiff_t oldtop, ptrdiff_t ef); +LUAI_FUNC void luaD_poscall (lua_State *L, CallInfo *ci, int nres); +LUAI_FUNC int luaD_reallocstack (lua_State *L, int newsize, int raiseerror); +LUAI_FUNC int luaD_growstack (lua_State *L, int n, int raiseerror); +LUAI_FUNC void luaD_shrinkstack (lua_State *L); +LUAI_FUNC void luaD_inctop (lua_State *L); + +LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode); +LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud); + +#endif + diff --git a/include/lua/lfunc.h b/include/lua/lfunc.h new file mode 100644 index 0000000..dc1cebc --- /dev/null +++ b/include/lua/lfunc.h @@ -0,0 +1,64 @@ +/* +** $Id: lfunc.h $ +** Auxiliary functions to manipulate prototypes and closures +** See Copyright Notice in lua.h +*/ + +#ifndef lfunc_h +#define lfunc_h + + +#include "lobject.h" + + +#define sizeCclosure(n) (cast_int(offsetof(CClosure, upvalue)) + \ + cast_int(sizeof(TValue)) * (n)) + +#define sizeLclosure(n) (cast_int(offsetof(LClosure, upvals)) + \ + cast_int(sizeof(TValue *)) * (n)) + + +/* test whether thread is in 'twups' list */ +#define isintwups(L) (L->twups != L) + + +/* +** maximum number of upvalues in a closure (both C and Lua). (Value +** must fit in a VM register.) +*/ +#define MAXUPVAL 255 + + +#define upisopen(up) ((up)->v != &(up)->u.value) + + +#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v)) + + +/* +** maximum number of misses before giving up the cache of closures +** in prototypes +*/ +#define MAXMISS 10 + + + +/* special status to close upvalues preserving the top of the stack */ +#define CLOSEKTOP (-1) + + +LUAI_FUNC Proto *luaF_newproto (lua_State *L); +LUAI_FUNC CClosure *luaF_newCclosure (lua_State *L, int nupvals); +LUAI_FUNC LClosure *luaF_newLclosure (lua_State *L, int nupvals); +LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl); +LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_newtbcupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_closeupval (lua_State *L, StkId level); +LUAI_FUNC void luaF_close (lua_State *L, StkId level, int status, int yy); +LUAI_FUNC void luaF_unlinkupval (UpVal *uv); +LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f); +LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number, + int pc); + + +#endif diff --git a/include/lua/lgc.h b/include/lua/lgc.h new file mode 100644 index 0000000..073e2a4 --- /dev/null +++ b/include/lua/lgc.h @@ -0,0 +1,189 @@ +/* +** $Id: lgc.h $ +** Garbage Collector +** See Copyright Notice in lua.h +*/ + +#ifndef lgc_h +#define lgc_h + + +#include "lobject.h" +#include "lstate.h" + +/* +** Collectable objects may have one of three colors: white, which means +** the object is not marked; gray, which means the object is marked, but +** its references may be not marked; and black, which means that the +** object and all its references are marked. The main invariant of the +** garbage collector, while marking objects, is that a black object can +** never point to a white one. Moreover, any gray object must be in a +** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it +** can be visited again before finishing the collection cycle. (Open +** upvalues are an exception to this rule.) These lists have no meaning +** when the invariant is not being enforced (e.g., sweep phase). +*/ + + +/* +** Possible states of the Garbage Collector +*/ +#define GCSpropagate 0 +#define GCSenteratomic 1 +#define GCSatomic 2 +#define GCSswpallgc 3 +#define GCSswpfinobj 4 +#define GCSswptobefnz 5 +#define GCSswpend 6 +#define GCScallfin 7 +#define GCSpause 8 + + +#define issweepphase(g) \ + (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend) + + +/* +** macro to tell when main invariant (white objects cannot point to black +** ones) must be kept. During a collection, the sweep +** phase may break the invariant, as objects turned white may point to +** still-black objects. The invariant is restored when sweep ends and +** all objects are white again. +*/ + +#define keepinvariant(g) ((g)->gcstate <= GCSatomic) + + +/* +** some useful bit tricks +*/ +#define resetbits(x,m) ((x) &= cast_byte(~(m))) +#define setbits(x,m) ((x) |= (m)) +#define testbits(x,m) ((x) & (m)) +#define bitmask(b) (1<<(b)) +#define bit2mask(b1,b2) (bitmask(b1) | bitmask(b2)) +#define l_setbit(x,b) setbits(x, bitmask(b)) +#define resetbit(x,b) resetbits(x, bitmask(b)) +#define testbit(x,b) testbits(x, bitmask(b)) + + +/* +** Layout for bit use in 'marked' field. First three bits are +** used for object "age" in generational mode. Last bit is used +** by tests. +*/ +#define WHITE0BIT 3 /* object is white (type 0) */ +#define WHITE1BIT 4 /* object is white (type 1) */ +#define BLACKBIT 5 /* object is black */ +#define FINALIZEDBIT 6 /* object has been marked for finalization */ + +#define TESTBIT 7 + + + +#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) + + +#define iswhite(x) testbits((x)->marked, WHITEBITS) +#define isblack(x) testbit((x)->marked, BLACKBIT) +#define isgray(x) /* neither white nor black */ \ + (!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT))) + +#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT) + +#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS) +#define isdeadm(ow,m) ((m) & (ow)) +#define isdead(g,v) isdeadm(otherwhite(g), (v)->marked) + +#define changewhite(x) ((x)->marked ^= WHITEBITS) +#define nw2black(x) \ + check_exp(!iswhite(x), l_setbit((x)->marked, BLACKBIT)) + +#define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS) + + +/* object age in generational mode */ +#define G_NEW 0 /* created in current cycle */ +#define G_SURVIVAL 1 /* created in previous cycle */ +#define G_OLD0 2 /* marked old by frw. barrier in this cycle */ +#define G_OLD1 3 /* first full cycle as old */ +#define G_OLD 4 /* really old object (not to be visited) */ +#define G_TOUCHED1 5 /* old object touched this cycle */ +#define G_TOUCHED2 6 /* old object touched in previous cycle */ + +#define AGEBITS 7 /* all age bits (111) */ + +#define getage(o) ((o)->marked & AGEBITS) +#define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a)) +#define isold(o) (getage(o) > G_SURVIVAL) + +#define changeage(o,f,t) \ + check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t))) + + +/* Default Values for GC parameters */ +#define LUAI_GENMAJORMUL 100 +#define LUAI_GENMINORMUL 20 + +/* wait memory to double before starting new cycle */ +#define LUAI_GCPAUSE 200 + +/* +** some gc parameters are stored divided by 4 to allow a maximum value +** up to 1023 in a 'lu_byte'. +*/ +#define getgcparam(p) ((p) * 4) +#define setgcparam(p,v) ((p) = (v) / 4) + +#define LUAI_GCMUL 100 + +/* how much to allocate before next GC step (log2) */ +#define LUAI_GCSTEPSIZE 13 /* 8 KB */ + + +/* +** Check whether the declared GC mode is generational. While in +** generational mode, the collector can go temporarily to incremental +** mode to improve performance. This is signaled by 'g->lastatomic != 0'. +*/ +#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0) + +/* +** Does one step of collection when debt becomes positive. 'pre'/'pos' +** allows some adjustments to be done only when needed. macro +** 'condchangemem' is used only for heavy tests (forcing a full +** GC cycle on every opportunity) +*/ +#define luaC_condGC(L,pre,pos) \ + { if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \ + condchangemem(L,pre,pos); } + +/* more often than not, 'pre'/'pos' are empty */ +#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0) + + +#define luaC_barrier(L,p,v) ( \ + (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ + luaC_barrier_(L,obj2gco(p),gcvalue(v)) : cast_void(0)) + +#define luaC_barrierback(L,p,v) ( \ + (iscollectable(v) && isblack(p) && iswhite(gcvalue(v))) ? \ + luaC_barrierback_(L,p) : cast_void(0)) + +#define luaC_objbarrier(L,p,o) ( \ + (isblack(p) && iswhite(o)) ? \ + luaC_barrier_(L,obj2gco(p),obj2gco(o)) : cast_void(0)) + +LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_freeallobjects (lua_State *L); +LUAI_FUNC void luaC_step (lua_State *L); +LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask); +LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency); +LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz); +LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v); +LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o); +LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt); +LUAI_FUNC void luaC_changemode (lua_State *L, int newmode); + + +#endif diff --git a/include/lua/ljumptab.h b/include/lua/ljumptab.h new file mode 100644 index 0000000..8306f25 --- /dev/null +++ b/include/lua/ljumptab.h @@ -0,0 +1,112 @@ +/* +** $Id: ljumptab.h $ +** Jump Table for the Lua interpreter +** See Copyright Notice in lua.h +*/ + + +#undef vmdispatch +#undef vmcase +#undef vmbreak + +#define vmdispatch(x) goto *disptab[x]; + +#define vmcase(l) L_##l: + +#define vmbreak vmfetch(); vmdispatch(GET_OPCODE(i)); + + +static const void *const disptab[NUM_OPCODES] = { + +#if 0 +** you can update the following list with this command: +** +** sed -n '/^OP_/\!d; s/OP_/\&\&L_OP_/ ; s/,.*/,/ ; s/\/.*// ; p' lopcodes.h +** +#endif + +&&L_OP_MOVE, +&&L_OP_LOADI, +&&L_OP_LOADF, +&&L_OP_LOADK, +&&L_OP_LOADKX, +&&L_OP_LOADFALSE, +&&L_OP_LFALSESKIP, +&&L_OP_LOADTRUE, +&&L_OP_LOADNIL, +&&L_OP_GETUPVAL, +&&L_OP_SETUPVAL, +&&L_OP_GETTABUP, +&&L_OP_GETTABLE, +&&L_OP_GETI, +&&L_OP_GETFIELD, +&&L_OP_SETTABUP, +&&L_OP_SETTABLE, +&&L_OP_SETI, +&&L_OP_SETFIELD, +&&L_OP_NEWTABLE, +&&L_OP_SELF, +&&L_OP_ADDI, +&&L_OP_ADDK, +&&L_OP_SUBK, +&&L_OP_MULK, +&&L_OP_MODK, +&&L_OP_POWK, +&&L_OP_DIVK, +&&L_OP_IDIVK, +&&L_OP_BANDK, +&&L_OP_BORK, +&&L_OP_BXORK, +&&L_OP_SHRI, +&&L_OP_SHLI, +&&L_OP_ADD, +&&L_OP_SUB, +&&L_OP_MUL, +&&L_OP_MOD, +&&L_OP_POW, +&&L_OP_DIV, +&&L_OP_IDIV, +&&L_OP_BAND, +&&L_OP_BOR, +&&L_OP_BXOR, +&&L_OP_SHL, +&&L_OP_SHR, +&&L_OP_MMBIN, +&&L_OP_MMBINI, +&&L_OP_MMBINK, +&&L_OP_UNM, +&&L_OP_BNOT, +&&L_OP_NOT, +&&L_OP_LEN, +&&L_OP_CONCAT, +&&L_OP_CLOSE, +&&L_OP_TBC, +&&L_OP_JMP, +&&L_OP_EQ, +&&L_OP_LT, +&&L_OP_LE, +&&L_OP_EQK, +&&L_OP_EQI, +&&L_OP_LTI, +&&L_OP_LEI, +&&L_OP_GTI, +&&L_OP_GEI, +&&L_OP_TEST, +&&L_OP_TESTSET, +&&L_OP_CALL, +&&L_OP_TAILCALL, +&&L_OP_RETURN, +&&L_OP_RETURN0, +&&L_OP_RETURN1, +&&L_OP_FORLOOP, +&&L_OP_FORPREP, +&&L_OP_TFORPREP, +&&L_OP_TFORCALL, +&&L_OP_TFORLOOP, +&&L_OP_SETLIST, +&&L_OP_CLOSURE, +&&L_OP_VARARG, +&&L_OP_VARARGPREP, +&&L_OP_EXTRAARG + +}; diff --git a/include/lua/llex.h b/include/lua/llex.h new file mode 100644 index 0000000..389d2f8 --- /dev/null +++ b/include/lua/llex.h @@ -0,0 +1,91 @@ +/* +** $Id: llex.h $ +** Lexical Analyzer +** See Copyright Notice in lua.h +*/ + +#ifndef llex_h +#define llex_h + +#include + +#include "lobject.h" +#include "lzio.h" + + +/* +** Single-char tokens (terminal symbols) are represented by their own +** numeric code. Other tokens start at the following value. +*/ +#define FIRST_RESERVED (UCHAR_MAX + 1) + + +#if !defined(LUA_ENV) +#define LUA_ENV "_ENV" +#endif + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER RESERVED" +*/ +enum RESERVED { + /* terminal symbols denoted by reserved words */ + TK_AND = FIRST_RESERVED, TK_BREAK, + TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION, + TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT, + TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE, + /* other terminal symbols */ + TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, + TK_SHL, TK_SHR, + TK_DBCOLON, TK_EOS, + TK_FLT, TK_INT, TK_NAME, TK_STRING +}; + +/* number of reserved words */ +#define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1)) + + +typedef union { + lua_Number r; + lua_Integer i; + TString *ts; +} SemInfo; /* semantics information */ + + +typedef struct Token { + int token; + SemInfo seminfo; +} Token; + + +/* state of the lexer plus state of the parser when shared by all + functions */ +typedef struct LexState { + int current; /* current character (charint) */ + int linenumber; /* input line counter */ + int lastline; /* line of last token 'consumed' */ + Token t; /* current token */ + Token lookahead; /* look ahead token */ + struct FuncState *fs; /* current function (parser) */ + struct lua_State *L; + ZIO *z; /* input stream */ + Mbuffer *buff; /* buffer for tokens */ + Table *h; /* to avoid collection/reuse strings */ + struct Dyndata *dyd; /* dynamic structures used by the parser */ + TString *source; /* current source name */ + TString *envn; /* environment variable name */ +} LexState; + + +LUAI_FUNC void luaX_init (lua_State *L); +LUAI_FUNC void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, + TString *source, int firstchar); +LUAI_FUNC TString *luaX_newstring (LexState *ls, const char *str, size_t l); +LUAI_FUNC void luaX_next (LexState *ls); +LUAI_FUNC int luaX_lookahead (LexState *ls); +LUAI_FUNC l_noret luaX_syntaxerror (LexState *ls, const char *s); +LUAI_FUNC const char *luaX_token2str (LexState *ls, int token); + + +#endif diff --git a/include/lua/llimits.h b/include/lua/llimits.h new file mode 100644 index 0000000..025f1c8 --- /dev/null +++ b/include/lua/llimits.h @@ -0,0 +1,353 @@ +/* +** $Id: llimits.h $ +** Limits, basic types, and some other 'installation-dependent' definitions +** See Copyright Notice in lua.h +*/ + +#ifndef llimits_h +#define llimits_h + + +#include +#include + + +#include "lua.h" + + +/* +** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count +** the total memory used by Lua (in bytes). Usually, 'size_t' and +** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines. +*/ +#if defined(LUAI_MEM) /* { external definitions? */ +typedef LUAI_UMEM lu_mem; +typedef LUAI_MEM l_mem; +#elif LUAI_IS32INT /* }{ */ +typedef size_t lu_mem; +typedef ptrdiff_t l_mem; +#else /* 16-bit ints */ /* }{ */ +typedef unsigned long lu_mem; +typedef long l_mem; +#endif /* } */ + + +/* chars used as small naturals (so that 'char' is reserved for characters) */ +typedef unsigned char lu_byte; +typedef signed char ls_byte; + + +/* maximum value for size_t */ +#define MAX_SIZET ((size_t)(~(size_t)0)) + +/* maximum size visible for Lua (must be representable in a lua_Integer) */ +#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \ + : (size_t)(LUA_MAXINTEGER)) + + +#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)) + +#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1)) + + +#define MAX_INT INT_MAX /* maximum value of an int */ + + +/* +** floor of the log2 of the maximum signed value for integral type 't'. +** (That is, maximum 'n' such that '2^n' fits in the given signed type.) +*/ +#define log2maxs(t) (sizeof(t) * 8 - 2) + + +/* +** test whether an unsigned value is a power of 2 (or zero) +*/ +#define ispow2(x) (((x) & ((x) - 1)) == 0) + + +/* number of chars of a literal string without the ending \0 */ +#define LL(x) (sizeof(x)/sizeof(char) - 1) + + +/* +** conversion of pointer to unsigned integer: +** this is for hashing only; there is no problem if the integer +** cannot hold the whole pointer value +*/ +#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX)) + + + +/* types of 'usual argument conversions' for lua_Number and lua_Integer */ +typedef LUAI_UACNUMBER l_uacNumber; +typedef LUAI_UACINT l_uacInt; + + +/* +** Internal assertions for in-house debugging +*/ +#if defined LUAI_ASSERT +#undef NDEBUG +#include +#define lua_assert(c) assert(c) +#endif + +#if defined(lua_assert) +#define check_exp(c,e) (lua_assert(c), (e)) +/* to avoid problems with conditions too long */ +#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0)) +#else +#define lua_assert(c) ((void)0) +#define check_exp(c,e) (e) +#define lua_longassert(c) ((void)0) +#endif + +/* +** assertion for checking API calls +*/ +#if !defined(luai_apicheck) +#define luai_apicheck(l,e) ((void)l, lua_assert(e)) +#endif + +#define api_check(l,e,msg) luai_apicheck(l,(e) && msg) + + +/* macro to avoid warnings about unused variables */ +#if !defined(UNUSED) +#define UNUSED(x) ((void)(x)) +#endif + + +/* type casts (a macro highlights casts in the code) */ +#define cast(t, exp) ((t)(exp)) + +#define cast_void(i) cast(void, (i)) +#define cast_voidp(i) cast(void *, (i)) +#define cast_num(i) cast(lua_Number, (i)) +#define cast_int(i) cast(int, (i)) +#define cast_uint(i) cast(unsigned int, (i)) +#define cast_byte(i) cast(lu_byte, (i)) +#define cast_uchar(i) cast(unsigned char, (i)) +#define cast_char(i) cast(char, (i)) +#define cast_charp(i) cast(char *, (i)) +#define cast_sizet(i) cast(size_t, (i)) + + +/* cast a signed lua_Integer to lua_Unsigned */ +#if !defined(l_castS2U) +#define l_castS2U(i) ((lua_Unsigned)(i)) +#endif + +/* +** cast a lua_Unsigned to a signed lua_Integer; this cast is +** not strict ISO C, but two-complement architectures should +** work fine. +*/ +#if !defined(l_castU2S) +#define l_castU2S(i) ((lua_Integer)(i)) +#endif + + +/* +** non-return type +*/ +#if !defined(l_noret) + +#if defined(__GNUC__) +#define l_noret void __attribute__((noreturn)) +#elif defined(_MSC_VER) && _MSC_VER >= 1200 +#define l_noret void __declspec(noreturn) +#else +#define l_noret void +#endif + +#endif + + +/* +** type for virtual-machine instructions; +** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h) +*/ +#if LUAI_IS32INT +typedef unsigned int l_uint32; +#else +typedef unsigned long l_uint32; +#endif + +typedef l_uint32 Instruction; + + + +/* +** Maximum length for short strings, that is, strings that are +** internalized. (Cannot be smaller than reserved words or tags for +** metamethods, as these strings must be internalized; +** #("function") = 8, #("__newindex") = 10.) +*/ +#if !defined(LUAI_MAXSHORTLEN) +#define LUAI_MAXSHORTLEN 40 +#endif + + +/* +** Initial size for the string table (must be power of 2). +** The Lua core alone registers ~50 strings (reserved words + +** metaevent keys + a few others). Libraries would typically add +** a few dozens more. +*/ +#if !defined(MINSTRTABSIZE) +#define MINSTRTABSIZE 128 +#endif + + +/* +** Size of cache for strings in the API. 'N' is the number of +** sets (better be a prime) and "M" is the size of each set (M == 1 +** makes a direct cache.) +*/ +#if !defined(STRCACHE_N) +#define STRCACHE_N 53 +#define STRCACHE_M 2 +#endif + + +/* minimum size for string buffer */ +#if !defined(LUA_MINBUFFER) +#define LUA_MINBUFFER 32 +#endif + + +/* +** Maximum depth for nested C calls, syntactical nested non-terminals, +** and other features implemented through recursion in C. (Value must +** fit in a 16-bit unsigned integer. It must also be compatible with +** the size of the C stack.) +*/ +#if !defined(LUAI_MAXCCALLS) +#define LUAI_MAXCCALLS 200 +#endif + + +/* +** macros that are executed whenever program enters the Lua core +** ('lua_lock') and leaves the core ('lua_unlock') +*/ +#if !defined(lua_lock) +#define lua_lock(L) ((void) 0) +#define lua_unlock(L) ((void) 0) +#endif + +/* +** macro executed during Lua functions at points where the +** function can yield. +*/ +#if !defined(luai_threadyield) +#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);} +#endif + + +/* +** these macros allow user-specific actions when a thread is +** created/deleted/resumed/yielded. +*/ +#if !defined(luai_userstateopen) +#define luai_userstateopen(L) ((void)L) +#endif + +#if !defined(luai_userstateclose) +#define luai_userstateclose(L) ((void)L) +#endif + +#if !defined(luai_userstatethread) +#define luai_userstatethread(L,L1) ((void)L) +#endif + +#if !defined(luai_userstatefree) +#define luai_userstatefree(L,L1) ((void)L) +#endif + +#if !defined(luai_userstateresume) +#define luai_userstateresume(L,n) ((void)L) +#endif + +#if !defined(luai_userstateyield) +#define luai_userstateyield(L,n) ((void)L) +#endif + + + +/* +** The luai_num* macros define the primitive operations over numbers. +*/ + +/* floor division (defined as 'floor(a/b)') */ +#if !defined(luai_numidiv) +#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b))) +#endif + +/* float division */ +#if !defined(luai_numdiv) +#define luai_numdiv(L,a,b) ((a)/(b)) +#endif + +/* +** modulo: defined as 'a - floor(a/b)*b'; the direct computation +** using this definition has several problems with rounding errors, +** so it is better to use 'fmod'. 'fmod' gives the result of +** 'a - trunc(a/b)*b', and therefore must be corrected when +** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a +** non-integer negative result: non-integer result is equivalent to +** a non-zero remainder 'm'; negative result is equivalent to 'a' and +** 'b' with different signs, or 'm' and 'b' with different signs +** (as the result 'm' of 'fmod' has the same sign of 'a'). +*/ +#if !defined(luai_nummod) +#define luai_nummod(L,a,b,m) \ + { (void)L; (m) = l_mathop(fmod)(a,b); \ + if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); } +#endif + +/* exponentiation */ +#if !defined(luai_numpow) +#define luai_numpow(L,a,b) \ + ((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b)) +#endif + +/* the others are quite standard operations */ +#if !defined(luai_numadd) +#define luai_numadd(L,a,b) ((a)+(b)) +#define luai_numsub(L,a,b) ((a)-(b)) +#define luai_nummul(L,a,b) ((a)*(b)) +#define luai_numunm(L,a) (-(a)) +#define luai_numeq(a,b) ((a)==(b)) +#define luai_numlt(a,b) ((a)<(b)) +#define luai_numle(a,b) ((a)<=(b)) +#define luai_numgt(a,b) ((a)>(b)) +#define luai_numge(a,b) ((a)>=(b)) +#define luai_numisnan(a) (!luai_numeq((a), (a))) +#endif + + + + + +/* +** macro to control inclusion of some hard tests on stack reallocation +*/ +#if !defined(HARDSTACKTESTS) +#define condmovestack(L,pre,pos) ((void)0) +#else +/* realloc stack keeping its size */ +#define condmovestack(L,pre,pos) \ + { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } +#endif + +#if !defined(HARDMEMTESTS) +#define condchangemem(L,pre,pos) ((void)0) +#else +#define condchangemem(L,pre,pos) \ + { if (G(L)->gcrunning) { pre; luaC_fullgc(L, 0); pos; } } +#endif + +#endif diff --git a/include/lua/lmem.h b/include/lua/lmem.h new file mode 100644 index 0000000..8c75a44 --- /dev/null +++ b/include/lua/lmem.h @@ -0,0 +1,93 @@ +/* +** $Id: lmem.h $ +** Interface to Memory Manager +** See Copyright Notice in lua.h +*/ + +#ifndef lmem_h +#define lmem_h + + +#include + +#include "llimits.h" +#include "lua.h" + + +#define luaM_error(L) luaD_throw(L, LUA_ERRMEM) + + +/* +** This macro tests whether it is safe to multiply 'n' by the size of +** type 't' without overflows. Because 'e' is always constant, it avoids +** the runtime division MAX_SIZET/(e). +** (The macro is somewhat complex to avoid warnings: The 'sizeof' +** comparison avoids a runtime comparison when overflow cannot occur. +** The compiler should be able to optimize the real test by itself, but +** when it does it, it may give a warning about "comparison is always +** false due to limited range of data type"; the +1 tricks the compiler, +** avoiding this warning but also this optimization.) +*/ +#define luaM_testsize(n,e) \ + (sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e)) + +#define luaM_checksize(L,n,e) \ + (luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0)) + + +/* +** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that +** the result is not larger than 'n' and cannot overflow a 'size_t' +** when multiplied by the size of type 't'. (Assumes that 'n' is an +** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.) +*/ +#define luaM_limitN(n,t) \ + ((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \ + cast_uint((MAX_SIZET/sizeof(t)))) + + +/* +** Arrays of chars do not need any test +*/ +#define luaM_reallocvchar(L,b,on,n) \ + cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char))) + +#define luaM_freemem(L, b, s) luaM_free_(L, (b), (s)) +#define luaM_free(L, b) luaM_free_(L, (b), sizeof(*(b))) +#define luaM_freearray(L, b, n) luaM_free_(L, (b), (n)*sizeof(*(b))) + +#define luaM_new(L,t) cast(t*, luaM_malloc_(L, sizeof(t), 0)) +#define luaM_newvector(L,n,t) cast(t*, luaM_malloc_(L, (n)*sizeof(t), 0)) +#define luaM_newvectorchecked(L,n,t) \ + (luaM_checksize(L,n,sizeof(t)), luaM_newvector(L,n,t)) + +#define luaM_newobject(L,tag,s) luaM_malloc_(L, (s), tag) + +#define luaM_growvector(L,v,nelems,size,t,limit,e) \ + ((v)=cast(t *, luaM_growaux_(L,v,nelems,&(size),sizeof(t), \ + luaM_limitN(limit,t),e))) + +#define luaM_reallocvector(L, v,oldn,n,t) \ + (cast(t *, luaM_realloc_(L, v, cast_sizet(oldn) * sizeof(t), \ + cast_sizet(n) * sizeof(t)))) + +#define luaM_shrinkvector(L,v,size,fs,t) \ + ((v)=cast(t *, luaM_shrinkvector_(L, v, &(size), fs, sizeof(t)))) + +LUAI_FUNC l_noret luaM_toobig (lua_State *L); + +/* not to be called directly */ +LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize, + size_t size); +LUAI_FUNC void luaM_free_ (lua_State *L, void *block, size_t osize); +LUAI_FUNC void *luaM_growaux_ (lua_State *L, void *block, int nelems, + int *size, int size_elem, int limit, + const char *what); +LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem, + int final_n, int size_elem); +LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag); + +#endif + diff --git a/include/lua/lobject.h b/include/lua/lobject.h new file mode 100644 index 0000000..950bebb --- /dev/null +++ b/include/lua/lobject.h @@ -0,0 +1,800 @@ +/* +** $Id: lobject.h $ +** Type definitions for Lua objects +** See Copyright Notice in lua.h +*/ + + +#ifndef lobject_h +#define lobject_h + + +#include + + +#include "llimits.h" +#include "lua.h" + + +/* +** Extra types for collectable non-values +*/ +#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */ +#define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */ +#define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */ + + + +/* +** number of all possible types (including LUA_TNONE but excluding DEADKEY) +*/ +#define LUA_TOTALTYPES (LUA_TPROTO + 2) + + +/* +** tags for Tagged Values have the following use of bits: +** bits 0-3: actual tag (a LUA_T* constant) +** bits 4-5: variant bits +** bit 6: whether value is collectable +*/ + +/* add variant bits to a type */ +#define makevariant(t,v) ((t) | ((v) << 4)) + + + +/* +** Union of all Lua values +*/ +typedef union Value { + struct GCObject *gc; /* collectable objects */ + void *p; /* light userdata */ + lua_CFunction f; /* light C functions */ + lua_Integer i; /* integer numbers */ + lua_Number n; /* float numbers */ +} Value; + + +/* +** Tagged Values. This is the basic representation of values in Lua: +** an actual value plus a tag with its type. +*/ + +#define TValuefields Value value_; lu_byte tt_ + +typedef struct TValue { + TValuefields; +} TValue; + + +#define val_(o) ((o)->value_) +#define valraw(o) (&val_(o)) + + +/* raw type tag of a TValue */ +#define rawtt(o) ((o)->tt_) + +/* tag with no variants (bits 0-3) */ +#define novariant(t) ((t) & 0x0F) + +/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ +#define withvariant(t) ((t) & 0x3F) +#define ttypetag(o) withvariant(rawtt(o)) + +/* type of a TValue */ +#define ttype(o) (novariant(rawtt(o))) + + +/* Macros to test type */ +#define checktag(o,t) (rawtt(o) == (t)) +#define checktype(o,t) (ttype(o) == (t)) + + +/* Macros for internal tests */ + +/* collectable object has the same tag as the original value */ +#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt) + +/* +** Any value being manipulated by the program either is non +** collectable, or the collectable object has the right tag +** and it is not dead. The option 'L == NULL' allows other +** macros using this one to be used where L is not available. +*/ +#define checkliveness(L,obj) \ + ((void)L, lua_longassert(!iscollectable(obj) || \ + (righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj)))))) + + +/* Macros to set values */ + +/* set a value's tag */ +#define settt_(o,t) ((o)->tt_=(t)) + + +/* main macro to copy values (from 'obj1' to 'obj2') */ +#define setobj(L,obj1,obj2) \ + { TValue *io1=(obj1); const TValue *io2=(obj2); \ + io1->value_ = io2->value_; settt_(io1, io2->tt_); \ + checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } + +/* +** Different types of assignments, according to source and destination. +** (They are mostly equal now, but may be different in the future.) +*/ + +/* from stack to stack */ +#define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2)) +/* to stack (not from same stack) */ +#define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2) +/* from table to same table */ +#define setobjt2t setobj +/* to new object */ +#define setobj2n setobj +/* to table */ +#define setobj2t setobj + + +/* +** Entries in a Lua stack. Field 'tbclist' forms a list of all +** to-be-closed variables active in this stack. Dummy entries are +** used when the distance between two tbc variables does not fit +** in an unsigned short. They are represented by delta==0, and +** their real delta is always the maximum value that fits in +** that field. +*/ +typedef union StackValue { + TValue val; + struct { + TValuefields; + unsigned short delta; + } tbclist; +} StackValue; + + +/* index to stack elements */ +typedef StackValue *StkId; + +/* convert a 'StackValue' to a 'TValue' */ +#define s2v(o) (&(o)->val) + + + +/* +** {================================================================== +** Nil +** =================================================================== +*/ + +/* Standard nil */ +#define LUA_VNIL makevariant(LUA_TNIL, 0) + +/* Empty slot (which might be different from a slot containing nil) */ +#define LUA_VEMPTY makevariant(LUA_TNIL, 1) + +/* Value returned for a key not found in a table (absent key) */ +#define LUA_VABSTKEY makevariant(LUA_TNIL, 2) + + +/* macro to test for (any kind of) nil */ +#define ttisnil(v) checktype((v), LUA_TNIL) + + +/* macro to test for a standard nil */ +#define ttisstrictnil(o) checktag((o), LUA_VNIL) + + +#define setnilvalue(obj) settt_(obj, LUA_VNIL) + + +#define isabstkey(v) checktag((v), LUA_VABSTKEY) + + +/* +** macro to detect non-standard nils (used only in assertions) +*/ +#define isnonstrictnil(v) (ttisnil(v) && !ttisstrictnil(v)) + + +/* +** By default, entries with any kind of nil are considered empty. +** (In any definition, values associated with absent keys must also +** be accepted as empty.) +*/ +#define isempty(v) ttisnil(v) + + +/* macro defining a value corresponding to an absent key */ +#define ABSTKEYCONSTANT {NULL}, LUA_VABSTKEY + + +/* mark an entry as empty */ +#define setempty(v) settt_(v, LUA_VEMPTY) + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Booleans +** =================================================================== +*/ + + +#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0) +#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1) + +#define ttisboolean(o) checktype((o), LUA_TBOOLEAN) +#define ttisfalse(o) checktag((o), LUA_VFALSE) +#define ttistrue(o) checktag((o), LUA_VTRUE) + + +#define l_isfalse(o) (ttisfalse(o) || ttisnil(o)) + + +#define setbfvalue(obj) settt_(obj, LUA_VFALSE) +#define setbtvalue(obj) settt_(obj, LUA_VTRUE) + +/* }================================================================== */ + + +/* +** {================================================================== +** Threads +** =================================================================== +*/ + +#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0) + +#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD)) + +#define thvalue(o) check_exp(ttisthread(o), gco2th(val_(o).gc)) + +#define setthvalue(L,obj,x) \ + { TValue *io = (obj); lua_State *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTHREAD)); \ + checkliveness(L,io); } + +#define setthvalue2s(L,o,t) setthvalue(L,s2v(o),t) + +/* }================================================================== */ + + +/* +** {================================================================== +** Collectable Objects +** =================================================================== +*/ + +/* +** Common Header for all collectable objects (in macro form, to be +** included in other objects) +*/ +#define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked + + +/* Common type for all collectable objects */ +typedef struct GCObject { + CommonHeader; +} GCObject; + + +/* Bit mark for collectable types */ +#define BIT_ISCOLLECTABLE (1 << 6) + +#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE) + +/* mark a tag as collectable */ +#define ctb(t) ((t) | BIT_ISCOLLECTABLE) + +#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc) + +#define gcvalueraw(v) ((v).gc) + +#define setgcovalue(L,obj,x) \ + { TValue *io = (obj); GCObject *i_g=(x); \ + val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Numbers +** =================================================================== +*/ + +/* Variant tags for numbers */ +#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */ +#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */ + +#define ttisnumber(o) checktype((o), LUA_TNUMBER) +#define ttisfloat(o) checktag((o), LUA_VNUMFLT) +#define ttisinteger(o) checktag((o), LUA_VNUMINT) + +#define nvalue(o) check_exp(ttisnumber(o), \ + (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) +#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n) +#define ivalue(o) check_exp(ttisinteger(o), val_(o).i) + +#define fltvalueraw(v) ((v).n) +#define ivalueraw(v) ((v).i) + +#define setfltvalue(obj,x) \ + { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_VNUMFLT); } + +#define chgfltvalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisfloat(io)); val_(io).n=(x); } + +#define setivalue(obj,x) \ + { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_VNUMINT); } + +#define chgivalue(obj,x) \ + { TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); } + +/* }================================================================== */ + + +/* +** {================================================================== +** Strings +** =================================================================== +*/ + +/* Variant tags for strings */ +#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */ +#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */ + +#define ttisstring(o) checktype((o), LUA_TSTRING) +#define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR)) +#define ttislngstring(o) checktag((o), ctb(LUA_VLNGSTR)) + +#define tsvalueraw(v) (gco2ts((v).gc)) + +#define tsvalue(o) check_exp(ttisstring(o), gco2ts(val_(o).gc)) + +#define setsvalue(L,obj,x) \ + { TValue *io = (obj); TString *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \ + checkliveness(L,io); } + +/* set a string to the stack */ +#define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s) + +/* set a string to a new object */ +#define setsvalue2n setsvalue + + +/* +** Header for a string value. +*/ +typedef struct TString { + CommonHeader; + lu_byte extra; /* reserved words for short strings; "has hash" for longs */ + lu_byte shrlen; /* length for short strings */ + unsigned int hash; + union { + size_t lnglen; /* length for long strings */ + struct TString *hnext; /* linked list for hash table */ + } u; + char contents[1]; +} TString; + + + +/* +** Get the actual string (array of bytes) from a 'TString'. +*/ +#define getstr(ts) ((ts)->contents) + + +/* get the actual string (array of bytes) from a Lua value */ +#define svalue(o) getstr(tsvalue(o)) + +/* get string length from 'TString *s' */ +#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen) + +/* get string length from 'TValue *o' */ +#define vslen(o) tsslen(tsvalue(o)) + +/* }================================================================== */ + + +/* +** {================================================================== +** Userdata +** =================================================================== +*/ + + +/* +** Light userdata should be a variant of userdata, but for compatibility +** reasons they are also different types. +*/ +#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0) + +#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0) + +#define ttislightuserdata(o) checktag((o), LUA_VLIGHTUSERDATA) +#define ttisfulluserdata(o) checktag((o), ctb(LUA_VUSERDATA)) + +#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p) +#define uvalue(o) check_exp(ttisfulluserdata(o), gco2u(val_(o).gc)) + +#define pvalueraw(v) ((v).p) + +#define setpvalue(obj,x) \ + { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_VLIGHTUSERDATA); } + +#define setuvalue(L,obj,x) \ + { TValue *io = (obj); Udata *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VUSERDATA)); \ + checkliveness(L,io); } + + +/* Ensures that addresses after this type are always fully aligned. */ +typedef union UValue { + TValue uv; + LUAI_MAXALIGN; /* ensures maximum alignment for udata bytes */ +} UValue; + + +/* +** Header for userdata with user values; +** memory area follows the end of this structure. +*/ +typedef struct Udata { + CommonHeader; + unsigned short nuvalue; /* number of user values */ + size_t len; /* number of bytes */ + struct Table *metatable; + GCObject *gclist; + UValue uv[1]; /* user values */ +} Udata; + + +/* +** Header for userdata with no user values. These userdata do not need +** to be gray during GC, and therefore do not need a 'gclist' field. +** To simplify, the code always use 'Udata' for both kinds of userdata, +** making sure it never accesses 'gclist' on userdata with no user values. +** This structure here is used only to compute the correct size for +** this representation. (The 'bindata' field in its end ensures correct +** alignment for binary data following this header.) +*/ +typedef struct Udata0 { + CommonHeader; + unsigned short nuvalue; /* number of user values */ + size_t len; /* number of bytes */ + struct Table *metatable; + union {LUAI_MAXALIGN;} bindata; +} Udata0; + + +/* compute the offset of the memory area of a userdata */ +#define udatamemoffset(nuv) \ + ((nuv) == 0 ? offsetof(Udata0, bindata) \ + : offsetof(Udata, uv) + (sizeof(UValue) * (nuv))) + +/* get the address of the memory block inside 'Udata' */ +#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue)) + +/* compute the size of a userdata */ +#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb)) + +/* }================================================================== */ + + +/* +** {================================================================== +** Prototypes +** =================================================================== +*/ + +#define LUA_VPROTO makevariant(LUA_TPROTO, 0) + + +/* +** Description of an upvalue for function prototypes +*/ +typedef struct Upvaldesc { + TString *name; /* upvalue name (for debug information) */ + lu_byte instack; /* whether it is in stack (register) */ + lu_byte idx; /* index of upvalue (in stack or in outer function's list) */ + lu_byte kind; /* kind of corresponding variable */ +} Upvaldesc; + + +/* +** Description of a local variable for function prototypes +** (used for debug information) +*/ +typedef struct LocVar { + TString *varname; + int startpc; /* first point where variable is active */ + int endpc; /* first point where variable is dead */ +} LocVar; + + +/* +** Associates the absolute line source for a given instruction ('pc'). +** The array 'lineinfo' gives, for each instruction, the difference in +** lines from the previous instruction. When that difference does not +** fit into a byte, Lua saves the absolute line for that instruction. +** (Lua also saves the absolute line periodically, to speed up the +** computation of a line number: we can use binary search in the +** absolute-line array, but we must traverse the 'lineinfo' array +** linearly to compute a line.) +*/ +typedef struct AbsLineInfo { + int pc; + int line; +} AbsLineInfo; + +/* +** Function Prototypes +*/ +typedef struct Proto { + CommonHeader; + lu_byte numparams; /* number of fixed (named) parameters */ + lu_byte is_vararg; + lu_byte maxstacksize; /* number of registers needed by this function */ + int sizeupvalues; /* size of 'upvalues' */ + int sizek; /* size of 'k' */ + int sizecode; + int sizelineinfo; + int sizep; /* size of 'p' */ + int sizelocvars; + int sizeabslineinfo; /* size of 'abslineinfo' */ + int linedefined; /* debug information */ + int lastlinedefined; /* debug information */ + TValue *k; /* constants used by the function */ + Instruction *code; /* opcodes */ + struct Proto **p; /* functions defined inside the function */ + Upvaldesc *upvalues; /* upvalue information */ + ls_byte *lineinfo; /* information about source lines (debug information) */ + AbsLineInfo *abslineinfo; /* idem */ + LocVar *locvars; /* information about local variables (debug information) */ + TString *source; /* used for debug information */ + GCObject *gclist; +} Proto; + +/* }================================================================== */ + + +/* +** {================================================================== +** Functions +** =================================================================== +*/ + +#define LUA_VUPVAL makevariant(LUA_TUPVAL, 0) + + +/* Variant tags for functions */ +#define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */ +#define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */ +#define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */ + +#define ttisfunction(o) checktype(o, LUA_TFUNCTION) +#define ttisLclosure(o) checktag((o), ctb(LUA_VLCL)) +#define ttislcf(o) checktag((o), LUA_VLCF) +#define ttisCclosure(o) checktag((o), ctb(LUA_VCCL)) +#define ttisclosure(o) (ttisLclosure(o) || ttisCclosure(o)) + + +#define isLfunction(o) ttisLclosure(o) + +#define clvalue(o) check_exp(ttisclosure(o), gco2cl(val_(o).gc)) +#define clLvalue(o) check_exp(ttisLclosure(o), gco2lcl(val_(o).gc)) +#define fvalue(o) check_exp(ttislcf(o), val_(o).f) +#define clCvalue(o) check_exp(ttisCclosure(o), gco2ccl(val_(o).gc)) + +#define fvalueraw(v) ((v).f) + +#define setclLvalue(L,obj,x) \ + { TValue *io = (obj); LClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VLCL)); \ + checkliveness(L,io); } + +#define setclLvalue2s(L,o,cl) setclLvalue(L,s2v(o),cl) + +#define setfvalue(obj,x) \ + { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_VLCF); } + +#define setclCvalue(L,obj,x) \ + { TValue *io = (obj); CClosure *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VCCL)); \ + checkliveness(L,io); } + + +/* +** Upvalues for Lua closures +*/ +typedef struct UpVal { + CommonHeader; + lu_byte tbc; /* true if it represents a to-be-closed variable */ + TValue *v; /* points to stack or to its own value */ + union { + struct { /* (when open) */ + struct UpVal *next; /* linked list */ + struct UpVal **previous; + } open; + TValue value; /* the value (when closed) */ + } u; +} UpVal; + + + +#define ClosureHeader \ + CommonHeader; lu_byte nupvalues; GCObject *gclist + +typedef struct CClosure { + ClosureHeader; + lua_CFunction f; + TValue upvalue[1]; /* list of upvalues */ +} CClosure; + + +typedef struct LClosure { + ClosureHeader; + struct Proto *p; + UpVal *upvals[1]; /* list of upvalues */ +} LClosure; + + +typedef union Closure { + CClosure c; + LClosure l; +} Closure; + + +#define getproto(o) (clLvalue(o)->p) + +/* }================================================================== */ + + +/* +** {================================================================== +** Tables +** =================================================================== +*/ + +#define LUA_VTABLE makevariant(LUA_TTABLE, 0) + +#define ttistable(o) checktag((o), ctb(LUA_VTABLE)) + +#define hvalue(o) check_exp(ttistable(o), gco2t(val_(o).gc)) + +#define sethvalue(L,obj,x) \ + { TValue *io = (obj); Table *x_ = (x); \ + val_(io).gc = obj2gco(x_); settt_(io, ctb(LUA_VTABLE)); \ + checkliveness(L,io); } + +#define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h) + + +/* +** Nodes for Hash tables: A pack of two TValue's (key-value pairs) +** plus a 'next' field to link colliding entries. The distribution +** of the key's fields ('key_tt' and 'key_val') not forming a proper +** 'TValue' allows for a smaller size for 'Node' both in 4-byte +** and 8-byte alignments. +*/ +typedef union Node { + struct NodeKey { + TValuefields; /* fields for value */ + lu_byte key_tt; /* key type */ + int next; /* for chaining */ + Value key_val; /* key value */ + } u; + TValue i_val; /* direct access to node's value as a proper 'TValue' */ +} Node; + + +/* copy a value into a key */ +#define setnodekey(L,node,obj) \ + { Node *n_=(node); const TValue *io_=(obj); \ + n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \ + checkliveness(L,io_); } + + +/* copy a value from a key */ +#define getnodekey(L,obj,node) \ + { TValue *io_=(obj); const Node *n_=(node); \ + io_->value_ = n_->u.key_val; io_->tt_ = n_->u.key_tt; \ + checkliveness(L,io_); } + + +/* +** About 'alimit': if 'isrealasize(t)' is true, then 'alimit' is the +** real size of 'array'. Otherwise, the real size of 'array' is the +** smallest power of two not smaller than 'alimit' (or zero iff 'alimit' +** is zero); 'alimit' is then used as a hint for #t. +*/ + +#define BITRAS (1 << 7) +#define isrealasize(t) (!((t)->flags & BITRAS)) +#define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS)) +#define setnorealasize(t) ((t)->flags |= BITRAS) + + +typedef struct Table { + CommonHeader; + lu_byte flags; /* 1<

u.key_tt) +#define keyval(node) ((node)->u.key_val) + +#define keyisnil(node) (keytt(node) == LUA_TNIL) +#define keyisinteger(node) (keytt(node) == LUA_VNUMINT) +#define keyival(node) (keyval(node).i) +#define keyisshrstr(node) (keytt(node) == ctb(LUA_VSHRSTR)) +#define keystrval(node) (gco2ts(keyval(node).gc)) + +#define setnilkey(node) (keytt(node) = LUA_TNIL) + +#define keyiscollectable(n) (keytt(n) & BIT_ISCOLLECTABLE) + +#define gckey(n) (keyval(n).gc) +#define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL) + + +/* +** Dead keys in tables have the tag DEADKEY but keep their original +** gcvalue. This distinguishes them from regular keys but allows them to +** be found when searched in a special way. ('next' needs that to find +** keys removed from a table during a traversal.) +*/ +#define setdeadkey(node) (keytt(node) = LUA_TDEADKEY) +#define keyisdead(node) (keytt(node) == LUA_TDEADKEY) + +/* }================================================================== */ + + + +/* +** 'module' operation for hashing (size is always a power of 2) +*/ +#define lmod(s,size) \ + (check_exp((size&(size-1))==0, (cast_int((s) & ((size)-1))))) + + +#define twoto(x) (1<<(x)) +#define sizenode(t) (twoto((t)->lsizenode)) + + +/* size of buffer for 'luaO_utf8esc' function */ +#define UTF8BUFFSZ 8 + +LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x); +LUAI_FUNC int luaO_ceillog2 (unsigned int x); +LUAI_FUNC int luaO_rawarith (lua_State *L, int op, const TValue *p1, + const TValue *p2, TValue *res); +LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1, + const TValue *p2, StkId res); +LUAI_FUNC size_t luaO_str2num (const char *s, TValue *o); +LUAI_FUNC int luaO_hexavalue (int c); +LUAI_FUNC void luaO_tostring (lua_State *L, TValue *obj); +LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt, + va_list argp); +LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...); +LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t srclen); + + +#endif + diff --git a/include/lua/lopcodes.h b/include/lua/lopcodes.h new file mode 100644 index 0000000..d6a47e5 --- /dev/null +++ b/include/lua/lopcodes.h @@ -0,0 +1,392 @@ +/* +** $Id: lopcodes.h $ +** Opcodes for Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lopcodes_h +#define lopcodes_h + +#include "llimits.h" + + +/*=========================================================================== + We assume that instructions are unsigned 32-bit integers. + All instructions have an opcode in the first 7 bits. + Instructions can have the following formats: + + 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 + 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 +iABC C(8) | B(8) |k| A(8) | Op(7) | +iABx Bx(17) | A(8) | Op(7) | +iAsBx sBx (signed)(17) | A(8) | Op(7) | +iAx Ax(25) | Op(7) | +isJ sJ(25) | Op(7) | + + A signed argument is represented in excess K: the represented value is + the written unsigned value minus K, where K is half the maximum for the + corresponding unsigned argument. +===========================================================================*/ + + +enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */ + + +/* +** size and position of opcode arguments. +*/ +#define SIZE_C 8 +#define SIZE_B 8 +#define SIZE_Bx (SIZE_C + SIZE_B + 1) +#define SIZE_A 8 +#define SIZE_Ax (SIZE_Bx + SIZE_A) +#define SIZE_sJ (SIZE_Bx + SIZE_A) + +#define SIZE_OP 7 + +#define POS_OP 0 + +#define POS_A (POS_OP + SIZE_OP) +#define POS_k (POS_A + SIZE_A) +#define POS_B (POS_k + 1) +#define POS_C (POS_B + SIZE_B) + +#define POS_Bx POS_k + +#define POS_Ax POS_A + +#define POS_sJ POS_A + + +/* +** limits for opcode arguments. +** we use (signed) 'int' to manipulate most arguments, +** so they must fit in ints. +*/ + +/* Check whether type 'int' has at least 'b' bits ('b' < 32) */ +#define L_INTHASBITS(b) ((UINT_MAX >> ((b) - 1)) >= 1) + + +#if L_INTHASBITS(SIZE_Bx) +#define MAXARG_Bx ((1<>1) /* 'sBx' is signed */ + + +#if L_INTHASBITS(SIZE_Ax) +#define MAXARG_Ax ((1<> 1) + + +#define MAXARG_A ((1<> 1) + +#define int2sC(i) ((i) + OFFSET_sC) +#define sC2int(i) ((i) - OFFSET_sC) + + +/* creates a mask with 'n' 1 bits at position 'p' */ +#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p)) + +/* creates a mask with 'n' 0 bits at position 'p' */ +#define MASK0(n,p) (~MASK1(n,p)) + +/* +** the following macros help to manipulate instructions +*/ + +#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0))) +#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \ + ((cast(Instruction, o)<>(pos)) & MASK1(size,0))) +#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \ + ((cast(Instruction, v)<> sC */ +OP_SHLI,/* A B sC R[A] := sC << R[B] */ + +OP_ADD,/* A B C R[A] := R[B] + R[C] */ +OP_SUB,/* A B C R[A] := R[B] - R[C] */ +OP_MUL,/* A B C R[A] := R[B] * R[C] */ +OP_MOD,/* A B C R[A] := R[B] % R[C] */ +OP_POW,/* A B C R[A] := R[B] ^ R[C] */ +OP_DIV,/* A B C R[A] := R[B] / R[C] */ +OP_IDIV,/* A B C R[A] := R[B] // R[C] */ + +OP_BAND,/* A B C R[A] := R[B] & R[C] */ +OP_BOR,/* A B C R[A] := R[B] | R[C] */ +OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */ +OP_SHL,/* A B C R[A] := R[B] << R[C] */ +OP_SHR,/* A B C R[A] := R[B] >> R[C] */ + +OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] */ +OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */ +OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ + +OP_UNM,/* A B R[A] := -R[B] */ +OP_BNOT,/* A B R[A] := ~R[B] */ +OP_NOT,/* A B R[A] := not R[B] */ +OP_LEN,/* A B R[A] := #R[B] (length operator) */ + +OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */ + +OP_CLOSE,/* A close all upvalues >= R[A] */ +OP_TBC,/* A mark variable A "to be closed" */ +OP_JMP,/* sJ pc += sJ */ +OP_EQ,/* A B k if ((R[A] == R[B]) ~= k) then pc++ */ +OP_LT,/* A B k if ((R[A] < R[B]) ~= k) then pc++ */ +OP_LE,/* A B k if ((R[A] <= R[B]) ~= k) then pc++ */ + +OP_EQK,/* A B k if ((R[A] == K[B]) ~= k) then pc++ */ +OP_EQI,/* A sB k if ((R[A] == sB) ~= k) then pc++ */ +OP_LTI,/* A sB k if ((R[A] < sB) ~= k) then pc++ */ +OP_LEI,/* A sB k if ((R[A] <= sB) ~= k) then pc++ */ +OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */ +OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */ + +OP_TEST,/* A k if (not R[A] == k) then pc++ */ +OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] */ + +OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */ +OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */ + +OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */ +OP_RETURN0,/* return */ +OP_RETURN1,/* A return R[A] */ + +OP_FORLOOP,/* A Bx update counters; if loop continues then pc-=Bx; */ +OP_FORPREP,/* A Bx ; + if not to run then pc+=Bx+1; */ + +OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ +OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ +OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ + +OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ + +OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ + +OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */ + +OP_VARARGPREP,/*A (adjust vararg parameters) */ + +OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */ +} OpCode; + + +#define NUM_OPCODES ((int)(OP_EXTRAARG) + 1) + + + +/*=========================================================================== + Notes: + (*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then + 'top' is set to last_result+1, so next open instruction (OP_CALL, + OP_RETURN*, OP_SETLIST) may use 'top'. + + (*) In OP_VARARG, if (C == 0) then use actual number of varargs and + set top (like in OP_CALL with C == 0). + + (*) In OP_RETURN, if (B == 0) then return up to 'top'. + + (*) In OP_LOADKX and OP_NEWTABLE, the next instruction is always + OP_EXTRAARG. + + (*) In OP_SETLIST, if (B == 0) then real B = 'top'; if k, then + real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the + bits of C). + + (*) In OP_NEWTABLE, B is log2 of the hash size (which is always a + power of 2) plus 1, or zero for size zero. If not k, the array size + is C. Otherwise, the array size is EXTRAARG _ C. + + (*) For comparisons, k specifies what condition the test should accept + (true or false). + + (*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped + (the constant is the first operand). + + (*) All 'skips' (pc++) assume that next instruction is a jump. + + (*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the + function builds upvalues, which may need to be closed. C > 0 means + the function is vararg, so that its 'func' must be corrected before + returning; in this case, (C - 1) is its number of fixed parameters. + + (*) In comparisons with an immediate operand, C signals whether the + original operand was a float. (It must be corrected in case of + metamethods.) + +===========================================================================*/ + + +/* +** masks for instruction properties. The format is: +** bits 0-2: op mode +** bit 3: instruction set register A +** bit 4: operator is a test (next instruction must be a jump) +** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0) +** bit 6: instruction sets 'L->top' for next instruction (when C == 0) +** bit 7: instruction is an MM instruction (call a metamethod) +*/ + +LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];) + +#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 7)) +#define testAMode(m) (luaP_opmodes[m] & (1 << 3)) +#define testTMode(m) (luaP_opmodes[m] & (1 << 4)) +#define testITMode(m) (luaP_opmodes[m] & (1 << 5)) +#define testOTMode(m) (luaP_opmodes[m] & (1 << 6)) +#define testMMMode(m) (luaP_opmodes[m] & (1 << 7)) + +/* "out top" (set top for next instruction) */ +#define isOT(i) \ + ((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \ + GET_OPCODE(i) == OP_TAILCALL) + +/* "in top" (uses top from previous instruction) */ +#define isIT(i) (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0) + +#define opmode(mm,ot,it,t,a,m) \ + (((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m)) + + +/* number of list items to accumulate before a SETLIST instruction */ +#define LFIELDS_PER_FLUSH 50 + +#endif diff --git a/include/lua/lopnames.h b/include/lua/lopnames.h new file mode 100644 index 0000000..965cec9 --- /dev/null +++ b/include/lua/lopnames.h @@ -0,0 +1,103 @@ +/* +** $Id: lopnames.h $ +** Opcode names +** See Copyright Notice in lua.h +*/ + +#if !defined(lopnames_h) +#define lopnames_h + +#include + + +/* ORDER OP */ + +static const char *const opnames[] = { + "MOVE", + "LOADI", + "LOADF", + "LOADK", + "LOADKX", + "LOADFALSE", + "LFALSESKIP", + "LOADTRUE", + "LOADNIL", + "GETUPVAL", + "SETUPVAL", + "GETTABUP", + "GETTABLE", + "GETI", + "GETFIELD", + "SETTABUP", + "SETTABLE", + "SETI", + "SETFIELD", + "NEWTABLE", + "SELF", + "ADDI", + "ADDK", + "SUBK", + "MULK", + "MODK", + "POWK", + "DIVK", + "IDIVK", + "BANDK", + "BORK", + "BXORK", + "SHRI", + "SHLI", + "ADD", + "SUB", + "MUL", + "MOD", + "POW", + "DIV", + "IDIV", + "BAND", + "BOR", + "BXOR", + "SHL", + "SHR", + "MMBIN", + "MMBINI", + "MMBINK", + "UNM", + "BNOT", + "NOT", + "LEN", + "CONCAT", + "CLOSE", + "TBC", + "JMP", + "EQ", + "LT", + "LE", + "EQK", + "EQI", + "LTI", + "LEI", + "GTI", + "GEI", + "TEST", + "TESTSET", + "CALL", + "TAILCALL", + "RETURN", + "RETURN0", + "RETURN1", + "FORLOOP", + "FORPREP", + "TFORPREP", + "TFORCALL", + "TFORLOOP", + "SETLIST", + "CLOSURE", + "VARARG", + "VARARGPREP", + "EXTRAARG", + NULL +}; + +#endif + diff --git a/include/lua/lparser.h b/include/lua/lparser.h new file mode 100644 index 0000000..5e4500f --- /dev/null +++ b/include/lua/lparser.h @@ -0,0 +1,171 @@ +/* +** $Id: lparser.h $ +** Lua Parser +** See Copyright Notice in lua.h +*/ + +#ifndef lparser_h +#define lparser_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* +** Expression and variable descriptor. +** Code generation for variables and expressions can be delayed to allow +** optimizations; An 'expdesc' structure describes a potentially-delayed +** variable/expression. It has a description of its "main" value plus a +** list of conditional jumps that can also produce its value (generated +** by short-circuit operators 'and'/'or'). +*/ + +/* kinds of variables/expressions */ +typedef enum { + VVOID, /* when 'expdesc' describes the last expression of a list, + this kind means an empty list (so, no expression) */ + VNIL, /* constant nil */ + VTRUE, /* constant true */ + VFALSE, /* constant false */ + VK, /* constant in 'k'; info = index of constant in 'k' */ + VKFLT, /* floating constant; nval = numerical float value */ + VKINT, /* integer constant; ival = numerical integer value */ + VKSTR, /* string constant; strval = TString address; + (string is fixed by the lexer) */ + VNONRELOC, /* expression has its value in a fixed register; + info = result register */ + VLOCAL, /* local variable; var.ridx = register index; + var.vidx = relative index in 'actvar.arr' */ + VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ + VCONST, /* compile-time variable; + info = absolute index in 'actvar.arr' */ + VINDEXED, /* indexed variable; + ind.t = table register; + ind.idx = key's R index */ + VINDEXUP, /* indexed upvalue; + ind.t = table upvalue; + ind.idx = key's K index */ + VINDEXI, /* indexed variable with constant integer; + ind.t = table register; + ind.idx = key's value */ + VINDEXSTR, /* indexed variable with literal string; + ind.t = table register; + ind.idx = key's K index */ + VJMP, /* expression is a test/comparison; + info = pc of corresponding jump instruction */ + VRELOC, /* expression can put result in any register; + info = instruction pc */ + VCALL, /* expression is a function call; info = instruction pc */ + VVARARG /* vararg expression; info = instruction pc */ +} expkind; + + +#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) +#define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) + + +typedef struct expdesc { + expkind k; + union { + lua_Integer ival; /* for VKINT */ + lua_Number nval; /* for VKFLT */ + TString *strval; /* for VKSTR */ + int info; /* for generic use */ + struct { /* for indexed variables */ + short idx; /* index (R or "long" K) */ + lu_byte t; /* table (register or upvalue) */ + } ind; + struct { /* for local variables */ + lu_byte ridx; /* register holding the variable */ + unsigned short vidx; /* compiler index (in 'actvar.arr') */ + } var; + } u; + int t; /* patch list of 'exit when true' */ + int f; /* patch list of 'exit when false' */ +} expdesc; + + +/* kinds of variables */ +#define VDKREG 0 /* regular */ +#define RDKCONST 1 /* constant */ +#define RDKTOCLOSE 2 /* to-be-closed */ +#define RDKCTC 3 /* compile-time constant */ + +/* description of an active local variable */ +typedef union Vardesc { + struct { + TValuefields; /* constant value (if it is a compile-time constant) */ + lu_byte kind; + lu_byte ridx; /* register holding the variable */ + short pidx; /* index of the variable in the Proto's 'locvars' array */ + TString *name; /* variable name */ + } vd; + TValue k; /* constant value (if any) */ +} Vardesc; + + + +/* description of pending goto statements and label statements */ +typedef struct Labeldesc { + TString *name; /* label identifier */ + int pc; /* position in code */ + int line; /* line where it appeared */ + lu_byte nactvar; /* number of active variables in that position */ + lu_byte close; /* goto that escapes upvalues */ +} Labeldesc; + + +/* list of labels or gotos */ +typedef struct Labellist { + Labeldesc *arr; /* array */ + int n; /* number of entries in use */ + int size; /* array size */ +} Labellist; + + +/* dynamic structures used by the parser */ +typedef struct Dyndata { + struct { /* list of all active local variables */ + Vardesc *arr; + int n; + int size; + } actvar; + Labellist gt; /* list of pending gotos */ + Labellist label; /* list of active labels */ +} Dyndata; + + +/* control of blocks */ +struct BlockCnt; /* defined in lparser.c */ + + +/* state needed to generate code for a given function */ +typedef struct FuncState { + Proto *f; /* current function header */ + struct FuncState *prev; /* enclosing function */ + struct LexState *ls; /* lexical state */ + struct BlockCnt *bl; /* chain of current blocks */ + int pc; /* next position to code (equivalent to 'ncode') */ + int lasttarget; /* 'label' of last 'jump label' */ + int previousline; /* last line that was saved in 'lineinfo' */ + int nk; /* number of elements in 'k' */ + int np; /* number of elements in 'p' */ + int nabslineinfo; /* number of elements in 'abslineinfo' */ + int firstlocal; /* index of first local var (in Dyndata array) */ + int firstlabel; /* index of first label (in 'dyd->label->arr') */ + short ndebugvars; /* number of elements in 'f->locvars' */ + lu_byte nactvar; /* number of active local variables */ + lu_byte nups; /* number of upvalues */ + lu_byte freereg; /* first free register */ + lu_byte iwthabs; /* instructions issued since last absolute line info */ + lu_byte needclose; /* function needs to close upvalues when returning */ +} FuncState; + + +LUAI_FUNC int luaY_nvarstack (FuncState *fs); +LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, + Dyndata *dyd, const char *name, int firstchar); + + +#endif diff --git a/include/lua/lprefix.h b/include/lua/lprefix.h new file mode 100644 index 0000000..484f2ad --- /dev/null +++ b/include/lua/lprefix.h @@ -0,0 +1,45 @@ +/* +** $Id: lprefix.h $ +** Definitions for Lua code that must come before any other header file +** See Copyright Notice in lua.h +*/ + +#ifndef lprefix_h +#define lprefix_h + + +/* +** Allows POSIX/XSI stuff +*/ +#if !defined(LUA_USE_C89) /* { */ + +#if !defined(_XOPEN_SOURCE) +#define _XOPEN_SOURCE 600 +#elif _XOPEN_SOURCE == 0 +#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */ +#endif + +/* +** Allows manipulation of large files in gcc and some other compilers +*/ +#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS) +#define _LARGEFILE_SOURCE 1 +#define _FILE_OFFSET_BITS 64 +#endif + +#endif /* } */ + + +/* +** Windows stuff +*/ +#if defined(_WIN32) /* { */ + +#if !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */ +#endif + +#endif /* } */ + +#endif + diff --git a/include/lua/lstate.h b/include/lua/lstate.h new file mode 100644 index 0000000..c1283bb --- /dev/null +++ b/include/lua/lstate.h @@ -0,0 +1,404 @@ +/* +** $Id: lstate.h $ +** Global State +** See Copyright Notice in lua.h +*/ + +#ifndef lstate_h +#define lstate_h + +#include "lua.h" + +#include "lobject.h" +#include "ltm.h" +#include "lzio.h" + + +/* +** Some notes about garbage-collected objects: All objects in Lua must +** be kept somehow accessible until being freed, so all objects always +** belong to one (and only one) of these lists, using field 'next' of +** the 'CommonHeader' for the link: +** +** 'allgc': all objects not marked for finalization; +** 'finobj': all objects marked for finalization; +** 'tobefnz': all objects ready to be finalized; +** 'fixedgc': all objects that are not to be collected (currently +** only small strings, such as reserved words). +** +** For the generational collector, some of these lists have marks for +** generations. Each mark points to the first element in the list for +** that particular generation; that generation goes until the next mark. +** +** 'allgc' -> 'survival': new objects; +** 'survival' -> 'old': objects that survived one collection; +** 'old1' -> 'reallyold': objects that became old in last collection; +** 'reallyold' -> NULL: objects old for more than one cycle. +** +** 'finobj' -> 'finobjsur': new objects marked for finalization; +** 'finobjsur' -> 'finobjold1': survived """"; +** 'finobjold1' -> 'finobjrold': just old """"; +** 'finobjrold' -> NULL: really old """". +** +** All lists can contain elements older than their main ages, due +** to 'luaC_checkfinalizer' and 'udata2finalize', which move +** objects between the normal lists and the "marked for finalization" +** lists. Moreover, barriers can age young objects in young lists as +** OLD0, which then become OLD1. However, a list never contains +** elements younger than their main ages. +** +** The generational collector also uses a pointer 'firstold1', which +** points to the first OLD1 object in the list. It is used to optimize +** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc' +** and 'reallyold', but often the list has no OLD1 objects or they are +** after 'old1'.) Note the difference between it and 'old1': +** 'firstold1': no OLD1 objects before this point; there can be all +** ages after it. +** 'old1': no objects younger than OLD1 after this point. +*/ + +/* +** Moreover, there is another set of lists that control gray objects. +** These lists are linked by fields 'gclist'. (All objects that +** can become gray have such a field. The field is not the same +** in all objects, but it always has this name.) Any gray object +** must belong to one of these lists, and all objects in these lists +** must be gray (with two exceptions explained below): +** +** 'gray': regular gray objects, still waiting to be visited. +** 'grayagain': objects that must be revisited at the atomic phase. +** That includes +** - black objects got in a write barrier; +** - all kinds of weak tables during propagation phase; +** - all threads. +** 'weak': tables with weak values to be cleared; +** 'ephemeron': ephemeron tables with white->white entries; +** 'allweak': tables with weak keys and/or weak values to be cleared. +** +** The exceptions to that "gray rule" are: +** - TOUCHED2 objects in generational mode stay in a gray list (because +** they must be visited again at the end of the cycle), but they are +** marked black because assignments to them must activate barriers (to +** move them back to TOUCHED1). +** - Open upvales are kept gray to avoid barriers, but they stay out +** of gray lists. (They don't even have a 'gclist' field.) +*/ + + + +/* +** About 'nCcalls': This count has two parts: the lower 16 bits counts +** the number of recursive invocations in the C stack; the higher +** 16 bits counts the number of non-yieldable calls in the stack. +** (They are together so that we can change and save both with one +** instruction.) +*/ + + +/* true if this thread does not have non-yieldable calls in the stack */ +#define yieldable(L) (((L)->nCcalls & 0xffff0000) == 0) + +/* real number of C calls */ +#define getCcalls(L) ((L)->nCcalls & 0xffff) + + +/* Increment the number of non-yieldable calls */ +#define incnny(L) ((L)->nCcalls += 0x10000) + +/* Decrement the number of non-yieldable calls */ +#define decnny(L) ((L)->nCcalls -= 0x10000) + +/* Non-yieldable call increment */ +#define nyci (0x10000 | 1) + + + + +struct lua_longjmp; /* defined in ldo.c */ + + +/* +** Atomic type (relative to signals) to better ensure that 'lua_sethook' +** is thread safe +*/ +#if !defined(l_signalT) +#include +#define l_signalT sig_atomic_t +#endif + + +/* +** Extra stack space to handle TM calls and some other extras. This +** space is not included in 'stack_last'. It is used only to avoid stack +** checks, either because the element will be promptly popped or because +** there will be a stack check soon after the push. Function frames +** never use this extra space, so it does not need to be kept clean. +*/ +#define EXTRA_STACK 5 + + +#define BASIC_STACK_SIZE (2*LUA_MINSTACK) + +#define stacksize(th) cast_int((th)->stack_last - (th)->stack) + + +/* kinds of Garbage Collection */ +#define KGC_INC 0 /* incremental gc */ +#define KGC_GEN 1 /* generational gc */ + + +typedef struct stringtable { + TString **hash; + int nuse; /* number of elements */ + int size; +} stringtable; + + +/* +** Information about a call. +** About union 'u': +** - field 'l' is used only for Lua functions; +** - field 'c' is used only for C functions. +** About union 'u2': +** - field 'funcidx' is used only by C functions while doing a +** protected call; +** - field 'nyield' is used only while a function is "doing" an +** yield (from the yield until the next resume); +** - field 'nres' is used only while closing tbc variables when +** returning from a C function; +** - field 'transferinfo' is used only during call/returnhooks, +** before the function starts or after it ends. +*/ +typedef struct CallInfo { + StkId func; /* function index in the stack */ + StkId top; /* top for this function */ + struct CallInfo *previous, *next; /* dynamic call link */ + union { + struct { /* only for Lua functions */ + const Instruction *savedpc; + volatile l_signalT trap; + int nextraargs; /* # of extra arguments in vararg functions */ + } l; + struct { /* only for C functions */ + lua_KFunction k; /* continuation in case of yields */ + ptrdiff_t old_errfunc; + lua_KContext ctx; /* context info. in case of yields */ + } c; + } u; + union { + int funcidx; /* called-function index */ + int nyield; /* number of values yielded */ + int nres; /* number of values returned */ + struct { /* info about transferred values (for call/return hooks) */ + unsigned short ftransfer; /* offset of first value transferred */ + unsigned short ntransfer; /* number of values transferred */ + } transferinfo; + } u2; + short nresults; /* expected number of results from this function */ + unsigned short callstatus; +} CallInfo; + + +/* +** Bits in CallInfo status +*/ +#define CIST_OAH (1<<0) /* original value of 'allowhook' */ +#define CIST_C (1<<1) /* call is running a C function */ +#define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ +#define CIST_HOOKED (1<<3) /* call is running a debug hook */ +#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */ +#define CIST_TAIL (1<<5) /* call was tail called */ +#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ +#define CIST_FIN (1<<7) /* call is running a finalizer */ +#define CIST_TRAN (1<<8) /* 'ci' has transfer information */ +#define CIST_CLSRET (1<<9) /* function is closing tbc variables */ +/* Bits 10-12 are used for CIST_RECST (see below) */ +#define CIST_RECST 10 +#if defined(LUA_COMPAT_LT_LE) +#define CIST_LEQ (1<<13) /* using __lt for __le */ +#endif + + +/* +** Field CIST_RECST stores the "recover status", used to keep the error +** status while closing to-be-closed variables in coroutines, so that +** Lua can correctly resume after an yield from a __close method called +** because of an error. (Three bits are enough for error status.) +*/ +#define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7) +#define setcistrecst(ci,st) \ + check_exp(((st) & 7) == (st), /* status must fit in three bits */ \ + ((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \ + | ((st) << CIST_RECST))) + + +/* active function is a Lua function */ +#define isLua(ci) (!((ci)->callstatus & CIST_C)) + +/* call is running Lua code (not a hook) */ +#define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED))) + +/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */ +#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v)) +#define getoah(st) ((st) & CIST_OAH) + + +/* +** 'global state', shared by all threads of this state +*/ +typedef struct global_State { + lua_Alloc frealloc; /* function to reallocate memory */ + void *ud; /* auxiliary data to 'frealloc' */ + l_mem totalbytes; /* number of bytes currently allocated - GCdebt */ + l_mem GCdebt; /* bytes allocated not yet compensated by the collector */ + lu_mem GCestimate; /* an estimate of the non-garbage memory in use */ + lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */ + stringtable strt; /* hash table for strings */ + TValue l_registry; + TValue nilvalue; /* a nil value */ + unsigned int seed; /* randomized seed for hashes */ + lu_byte currentwhite; + lu_byte gcstate; /* state of garbage collector */ + lu_byte gckind; /* kind of GC running */ + lu_byte gcstopem; /* stops emergency collections */ + lu_byte genminormul; /* control for minor generational collections */ + lu_byte genmajormul; /* control for major generational collections */ + lu_byte gcrunning; /* true if GC is running */ + lu_byte gcemergency; /* true if this is an emergency collection */ + lu_byte gcpause; /* size of pause between successive GCs */ + lu_byte gcstepmul; /* GC "speed" */ + lu_byte gcstepsize; /* (log2 of) GC granularity */ + GCObject *allgc; /* list of all collectable objects */ + GCObject **sweepgc; /* current position of sweep in list */ + GCObject *finobj; /* list of collectable objects with finalizers */ + GCObject *gray; /* list of gray objects */ + GCObject *grayagain; /* list of objects to be traversed atomically */ + GCObject *weak; /* list of tables with weak values */ + GCObject *ephemeron; /* list of ephemeron tables (weak keys) */ + GCObject *allweak; /* list of all-weak tables */ + GCObject *tobefnz; /* list of userdata to be GC */ + GCObject *fixedgc; /* list of objects not to be collected */ + /* fields for generational collector */ + GCObject *survival; /* start of objects that survived one GC cycle */ + GCObject *old1; /* start of old1 objects */ + GCObject *reallyold; /* objects more than one cycle old ("really old") */ + GCObject *firstold1; /* first OLD1 object in the list (if any) */ + GCObject *finobjsur; /* list of survival objects with finalizers */ + GCObject *finobjold1; /* list of old1 objects with finalizers */ + GCObject *finobjrold; /* list of really old objects with finalizers */ + struct lua_State *twups; /* list of threads with open upvalues */ + lua_CFunction panic; /* to be called in unprotected errors */ + struct lua_State *mainthread; + TString *memerrmsg; /* message for memory-allocation errors */ + TString *tmname[TM_N]; /* array with tag-method names */ + struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */ + TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ + lua_WarnFunction warnf; /* warning function */ + void *ud_warn; /* auxiliary data to 'warnf' */ +} global_State; + + +/* +** 'per thread' state +*/ +struct lua_State { + CommonHeader; + lu_byte status; + lu_byte allowhook; + unsigned short nci; /* number of items in 'ci' list */ + StkId top; /* first free slot in the stack */ + global_State *l_G; + CallInfo *ci; /* call info for current function */ + StkId stack_last; /* end of stack (last element + 1) */ + StkId stack; /* stack base */ + UpVal *openupval; /* list of open upvalues in this stack */ + StkId tbclist; /* list of to-be-closed variables */ + GCObject *gclist; + struct lua_State *twups; /* list of threads with open upvalues */ + struct lua_longjmp *errorJmp; /* current error recover point */ + CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ + volatile lua_Hook hook; + ptrdiff_t errfunc; /* current error handling function (stack index) */ + l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ + int oldpc; /* last pc traced */ + int basehookcount; + int hookcount; + volatile l_signalT hookmask; +}; + + +#define G(L) (L->l_G) + +/* +** 'g->nilvalue' being a nil value flags that the state was completely +** build. +*/ +#define completestate(g) ttisnil(&g->nilvalue) + + +/* +** Union of all collectable objects (only for conversions) +** ISO C99, 6.5.2.3 p.5: +** "if a union contains several structures that share a common initial +** sequence [...], and if the union object currently contains one +** of these structures, it is permitted to inspect the common initial +** part of any of them anywhere that a declaration of the complete type +** of the union is visible." +*/ +union GCUnion { + GCObject gc; /* common header */ + struct TString ts; + struct Udata u; + union Closure cl; + struct Table h; + struct Proto p; + struct lua_State th; /* thread */ + struct UpVal upv; +}; + + +/* +** ISO C99, 6.7.2.1 p.14: +** "A pointer to a union object, suitably converted, points to each of +** its members [...], and vice versa." +*/ +#define cast_u(o) cast(union GCUnion *, (o)) + +/* macros to convert a GCObject into a specific value */ +#define gco2ts(o) \ + check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts)) +#define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u)) +#define gco2lcl(o) check_exp((o)->tt == LUA_VLCL, &((cast_u(o))->cl.l)) +#define gco2ccl(o) check_exp((o)->tt == LUA_VCCL, &((cast_u(o))->cl.c)) +#define gco2cl(o) \ + check_exp(novariant((o)->tt) == LUA_TFUNCTION, &((cast_u(o))->cl)) +#define gco2t(o) check_exp((o)->tt == LUA_VTABLE, &((cast_u(o))->h)) +#define gco2p(o) check_exp((o)->tt == LUA_VPROTO, &((cast_u(o))->p)) +#define gco2th(o) check_exp((o)->tt == LUA_VTHREAD, &((cast_u(o))->th)) +#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv)) + + +/* +** macro to convert a Lua object into a GCObject +** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.) +*/ +#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc)) + + +/* actual number of total bytes allocated */ +#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt) + +LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); +LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); +LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); +LUAI_FUNC void luaE_freeCI (lua_State *L); +LUAI_FUNC void luaE_shrinkCI (lua_State *L); +LUAI_FUNC void luaE_checkcstack (lua_State *L); +LUAI_FUNC void luaE_incCstack (lua_State *L); +LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); +LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); +LUAI_FUNC int luaE_resetthread (lua_State *L, int status); + + +#endif + diff --git a/include/lua/lstring.h b/include/lua/lstring.h new file mode 100644 index 0000000..450c239 --- /dev/null +++ b/include/lua/lstring.h @@ -0,0 +1,57 @@ +/* +** $Id: lstring.h $ +** String table (keep all strings handled by Lua) +** See Copyright Notice in lua.h +*/ + +#ifndef lstring_h +#define lstring_h + +#include "lgc.h" +#include "lobject.h" +#include "lstate.h" + + +/* +** Memory-allocation error message must be preallocated (it cannot +** be created after memory is exhausted) +*/ +#define MEMERRMSG "not enough memory" + + +/* +** Size of a TString: Size of the header plus space for the string +** itself (including final '\0'). +*/ +#define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char)) + +#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ + (sizeof(s)/sizeof(char))-1)) + + +/* +** test whether a string is a reserved word +*/ +#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0) + + +/* +** equality for short strings, which are always internalized +*/ +#define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) + + +LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); +LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); +LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); +LUAI_FUNC void luaS_resize (lua_State *L, int newsize); +LUAI_FUNC void luaS_clearcache (global_State *g); +LUAI_FUNC void luaS_init (lua_State *L); +LUAI_FUNC void luaS_remove (lua_State *L, TString *ts); +LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, int nuvalue); +LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l); +LUAI_FUNC TString *luaS_new (lua_State *L, const char *str); +LUAI_FUNC TString *luaS_createlngstrobj (lua_State *L, size_t l); + + +#endif diff --git a/include/lua/ltable.h b/include/lua/ltable.h new file mode 100644 index 0000000..7bbbcb2 --- /dev/null +++ b/include/lua/ltable.h @@ -0,0 +1,66 @@ +/* +** $Id: ltable.h $ +** Lua tables (hash) +** See Copyright Notice in lua.h +*/ + +#ifndef ltable_h +#define ltable_h + +#include "lobject.h" + + +#define gnode(t,i) (&(t)->node[i]) +#define gval(n) (&(n)->i_val) +#define gnext(n) ((n)->u.next) + + +/* +** Clear all bits of fast-access metamethods, which means that the table +** may have any of these metamethods. (First access that fails after the +** clearing will set the bit again.) +*/ +#define invalidateTMcache(t) ((t)->flags &= ~maskflags) + + +/* true when 't' is using 'dummynode' as its hash part */ +#define isdummy(t) ((t)->lastfree == NULL) + + +/* allocated size for hash nodes */ +#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t)) + + +/* returns the Node, given the value of a table entry */ +#define nodefromval(v) cast(Node *, (v)) + + +LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); +LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, + TValue *value); +LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); +LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); +LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, + TValue *value); +LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, + TValue *value); +LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, + const TValue *slot, TValue *value); +LUAI_FUNC Table *luaH_new (lua_State *L); +LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, + unsigned int nhsize); +LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize); +LUAI_FUNC void luaH_free (lua_State *L, Table *t); +LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key); +LUAI_FUNC lua_Unsigned luaH_getn (Table *t); +LUAI_FUNC unsigned int luaH_realasize (const Table *t); + + +#if defined(LUA_DEBUG) +LUAI_FUNC Node *luaH_mainposition (const Table *t, const TValue *key); +LUAI_FUNC int luaH_isdummy (const Table *t); +#endif + + +#endif diff --git a/include/lua/ltm.h b/include/lua/ltm.h new file mode 100644 index 0000000..73b833c --- /dev/null +++ b/include/lua/ltm.h @@ -0,0 +1,103 @@ +/* +** $Id: ltm.h $ +** Tag methods +** See Copyright Notice in lua.h +*/ + +#ifndef ltm_h +#define ltm_h + + +#include "lobject.h" + + +/* +* WARNING: if you change the order of this enumeration, +* grep "ORDER TM" and "ORDER OP" +*/ +typedef enum { + TM_INDEX, + TM_NEWINDEX, + TM_GC, + TM_MODE, + TM_LEN, + TM_EQ, /* last tag method with fast access */ + TM_ADD, + TM_SUB, + TM_MUL, + TM_MOD, + TM_POW, + TM_DIV, + TM_IDIV, + TM_BAND, + TM_BOR, + TM_BXOR, + TM_SHL, + TM_SHR, + TM_UNM, + TM_BNOT, + TM_LT, + TM_LE, + TM_CONCAT, + TM_CALL, + TM_CLOSE, + TM_N /* number of elements in the enum */ +} TMS; + + +/* +** Mask with 1 in all fast-access methods. A 1 in any of these bits +** in the flag of a (meta)table means the metatable does not have the +** corresponding metamethod field. (Bit 7 of the flag is used for +** 'isrealasize'.) +*/ +#define maskflags (~(~0u << (TM_EQ + 1))) + + +/* +** Test whether there is no tagmethod. +** (Because tagmethods use raw accesses, the result may be an "empty" nil.) +*/ +#define notm(tm) ttisnil(tm) + + +#define gfasttm(g,et,e) ((et) == NULL ? NULL : \ + ((et)->flags & (1u<<(e))) ? NULL : luaT_gettm(et, e, (g)->tmname[e])) + +#define fasttm(l,et,e) gfasttm(G(l), et, e) + +#define ttypename(x) luaT_typenames_[(x) + 1] + +LUAI_DDEC(const char *const luaT_typenames_[LUA_TOTALTYPES];) + + +LUAI_FUNC const char *luaT_objtypename (lua_State *L, const TValue *o); + +LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename); +LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, + TMS event); +LUAI_FUNC void luaT_init (lua_State *L); + +LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1, + const TValue *p2, const TValue *p3); +LUAI_FUNC void luaT_callTMres (lua_State *L, const TValue *f, + const TValue *p1, const TValue *p2, StkId p3); +LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, + StkId res, TMS event); +LUAI_FUNC void luaT_tryconcatTM (lua_State *L); +LUAI_FUNC void luaT_trybinassocTM (lua_State *L, const TValue *p1, + const TValue *p2, int inv, StkId res, TMS event); +LUAI_FUNC void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2, + int inv, StkId res, TMS event); +LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1, + const TValue *p2, TMS event); +LUAI_FUNC int luaT_callorderiTM (lua_State *L, const TValue *p1, int v2, + int inv, int isfloat, TMS event); + +LUAI_FUNC void luaT_adjustvarargs (lua_State *L, int nfixparams, + struct CallInfo *ci, const Proto *p); +LUAI_FUNC void luaT_getvarargs (lua_State *L, struct CallInfo *ci, + StkId where, int wanted); + + +#endif diff --git a/include/lua/lua.h b/include/lua/lua.h new file mode 100644 index 0000000..820535b --- /dev/null +++ b/include/lua/lua.h @@ -0,0 +1,518 @@ +/* +** $Id: lua.h $ +** Lua - A Scripting Language +** Lua.org, PUC-Rio, Brazil (http://www.lua.org) +** See Copyright Notice at the end of this file +*/ + + +#ifndef lua_h +#define lua_h + +#include +#include + + +#include "luaconf.h" + + +#define LUA_VERSION_MAJOR "5" +#define LUA_VERSION_MINOR "4" +#define LUA_VERSION_RELEASE "3" + +#define LUA_VERSION_NUM 504 +#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) + +#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE +#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2021 Lua.org, PUC-Rio" +#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes" + + +/* mark for precompiled code ('Lua') */ +#define LUA_SIGNATURE "\x1bLua" + +/* option for multiple returns in 'lua_pcall' and 'lua_call' */ +#define LUA_MULTRET (-1) + + +/* +** Pseudo-indices +** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty +** space after that to help overflow detection) +*/ +#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000) +#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i)) + + +/* thread status */ +#define LUA_OK 0 +#define LUA_YIELD 1 +#define LUA_ERRRUN 2 +#define LUA_ERRSYNTAX 3 +#define LUA_ERRMEM 4 +#define LUA_ERRERR 5 + + +typedef struct lua_State lua_State; + + +/* +** basic types +*/ +#define LUA_TNONE (-1) + +#define LUA_TNIL 0 +#define LUA_TBOOLEAN 1 +#define LUA_TLIGHTUSERDATA 2 +#define LUA_TNUMBER 3 +#define LUA_TSTRING 4 +#define LUA_TTABLE 5 +#define LUA_TFUNCTION 6 +#define LUA_TUSERDATA 7 +#define LUA_TTHREAD 8 + +#define LUA_NUMTYPES 9 + + + +/* minimum Lua stack available to a C function */ +#define LUA_MINSTACK 20 + + +/* predefined values in the registry */ +#define LUA_RIDX_MAINTHREAD 1 +#define LUA_RIDX_GLOBALS 2 +#define LUA_RIDX_LAST LUA_RIDX_GLOBALS + + +/* type of numbers in Lua */ +typedef LUA_NUMBER lua_Number; + + +/* type for integer functions */ +typedef LUA_INTEGER lua_Integer; + +/* unsigned integer type */ +typedef LUA_UNSIGNED lua_Unsigned; + +/* type for continuation-function contexts */ +typedef LUA_KCONTEXT lua_KContext; + + +/* +** Type for C functions registered with Lua +*/ +typedef int (*lua_CFunction) (lua_State *L); + +/* +** Type for continuation functions +*/ +typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx); + + +/* +** Type for functions that read/write blocks when loading/dumping Lua chunks +*/ +typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz); + +typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud); + + +/* +** Type for memory-allocation functions +*/ +typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize); + + +/* +** Type for warning functions +*/ +typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont); + + + + +/* +** generic extra include file +*/ +#if defined(LUA_USER_H) +#include LUA_USER_H +#endif + + +/* +** RCS ident string +*/ +extern const char lua_ident[]; + + +/* +** state manipulation +*/ +LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud); +LUA_API void (lua_close) (lua_State *L); +LUA_API lua_State *(lua_newthread) (lua_State *L); +LUA_API int (lua_resetthread) (lua_State *L); + +LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf); + + +LUA_API lua_Number (lua_version) (lua_State *L); + + +/* +** basic stack manipulation +*/ +LUA_API int (lua_absindex) (lua_State *L, int idx); +LUA_API int (lua_gettop) (lua_State *L); +LUA_API void (lua_settop) (lua_State *L, int idx); +LUA_API void (lua_pushvalue) (lua_State *L, int idx); +LUA_API void (lua_rotate) (lua_State *L, int idx, int n); +LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx); +LUA_API int (lua_checkstack) (lua_State *L, int n); + +LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n); + + +/* +** access functions (stack -> C) +*/ + +LUA_API int (lua_isnumber) (lua_State *L, int idx); +LUA_API int (lua_isstring) (lua_State *L, int idx); +LUA_API int (lua_iscfunction) (lua_State *L, int idx); +LUA_API int (lua_isinteger) (lua_State *L, int idx); +LUA_API int (lua_isuserdata) (lua_State *L, int idx); +LUA_API int (lua_type) (lua_State *L, int idx); +LUA_API const char *(lua_typename) (lua_State *L, int tp); + +LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum); +LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum); +LUA_API int (lua_toboolean) (lua_State *L, int idx); +LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len); +LUA_API lua_Unsigned (lua_rawlen) (lua_State *L, int idx); +LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx); +LUA_API void *(lua_touserdata) (lua_State *L, int idx); +LUA_API lua_State *(lua_tothread) (lua_State *L, int idx); +LUA_API const void *(lua_topointer) (lua_State *L, int idx); + + +/* +** Comparison and arithmetic functions +*/ + +#define LUA_OPADD 0 /* ORDER TM, ORDER OP */ +#define LUA_OPSUB 1 +#define LUA_OPMUL 2 +#define LUA_OPMOD 3 +#define LUA_OPPOW 4 +#define LUA_OPDIV 5 +#define LUA_OPIDIV 6 +#define LUA_OPBAND 7 +#define LUA_OPBOR 8 +#define LUA_OPBXOR 9 +#define LUA_OPSHL 10 +#define LUA_OPSHR 11 +#define LUA_OPUNM 12 +#define LUA_OPBNOT 13 + +LUA_API void (lua_arith) (lua_State *L, int op); + +#define LUA_OPEQ 0 +#define LUA_OPLT 1 +#define LUA_OPLE 2 + +LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2); +LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op); + + +/* +** push functions (C -> stack) +*/ +LUA_API void (lua_pushnil) (lua_State *L); +LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n); +LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n); +LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t len); +LUA_API const char *(lua_pushstring) (lua_State *L, const char *s); +LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt, + va_list argp); +LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...); +LUA_API void (lua_pushcclosure) (lua_State *L, lua_CFunction fn, int n); +LUA_API void (lua_pushboolean) (lua_State *L, int b); +LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p); +LUA_API int (lua_pushthread) (lua_State *L); + + +/* +** get functions (Lua -> stack) +*/ +LUA_API int (lua_getglobal) (lua_State *L, const char *name); +LUA_API int (lua_gettable) (lua_State *L, int idx); +LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k); +LUA_API int (lua_geti) (lua_State *L, int idx, lua_Integer n); +LUA_API int (lua_rawget) (lua_State *L, int idx); +LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n); +LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p); + +LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec); +LUA_API void *(lua_newuserdatauv) (lua_State *L, size_t sz, int nuvalue); +LUA_API int (lua_getmetatable) (lua_State *L, int objindex); +LUA_API int (lua_getiuservalue) (lua_State *L, int idx, int n); + + +/* +** set functions (stack -> Lua) +*/ +LUA_API void (lua_setglobal) (lua_State *L, const char *name); +LUA_API void (lua_settable) (lua_State *L, int idx); +LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k); +LUA_API void (lua_seti) (lua_State *L, int idx, lua_Integer n); +LUA_API void (lua_rawset) (lua_State *L, int idx); +LUA_API void (lua_rawseti) (lua_State *L, int idx, lua_Integer n); +LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p); +LUA_API int (lua_setmetatable) (lua_State *L, int objindex); +LUA_API int (lua_setiuservalue) (lua_State *L, int idx, int n); + + +/* +** 'load' and 'call' functions (load and run Lua code) +*/ +LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, + lua_KContext ctx, lua_KFunction k); +#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL) + +LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc, + lua_KContext ctx, lua_KFunction k); +#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL) + +LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, + const char *chunkname, const char *mode); + +LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip); + + +/* +** coroutine functions +*/ +LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx, + lua_KFunction k); +LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg, + int *nres); +LUA_API int (lua_status) (lua_State *L); +LUA_API int (lua_isyieldable) (lua_State *L); + +#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL) + + +/* +** Warning-related functions +*/ +LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud); +LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont); + + +/* +** garbage-collection function and options +*/ + +#define LUA_GCSTOP 0 +#define LUA_GCRESTART 1 +#define LUA_GCCOLLECT 2 +#define LUA_GCCOUNT 3 +#define LUA_GCCOUNTB 4 +#define LUA_GCSTEP 5 +#define LUA_GCSETPAUSE 6 +#define LUA_GCSETSTEPMUL 7 +#define LUA_GCISRUNNING 9 +#define LUA_GCGEN 10 +#define LUA_GCINC 11 + +LUA_API int (lua_gc) (lua_State *L, int what, ...); + + +/* +** miscellaneous functions +*/ + +LUA_API int (lua_error) (lua_State *L); + +LUA_API int (lua_next) (lua_State *L, int idx); + +LUA_API void (lua_concat) (lua_State *L, int n); +LUA_API void (lua_len) (lua_State *L, int idx); + +LUA_API size_t (lua_stringtonumber) (lua_State *L, const char *s); + +LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud); +LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud); + +LUA_API void (lua_toclose) (lua_State *L, int idx); +LUA_API void (lua_closeslot) (lua_State *L, int idx); + + +/* +** {============================================================== +** some useful macros +** =============================================================== +*/ + +#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE)) + +#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL) +#define lua_tointeger(L,i) lua_tointegerx(L,(i),NULL) + +#define lua_pop(L,n) lua_settop(L, -(n)-1) + +#define lua_newtable(L) lua_createtable(L, 0, 0) + +#define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n))) + +#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0) + +#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION) +#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE) +#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA) +#define lua_isnil(L,n) (lua_type(L, (n)) == LUA_TNIL) +#define lua_isboolean(L,n) (lua_type(L, (n)) == LUA_TBOOLEAN) +#define lua_isthread(L,n) (lua_type(L, (n)) == LUA_TTHREAD) +#define lua_isnone(L,n) (lua_type(L, (n)) == LUA_TNONE) +#define lua_isnoneornil(L, n) (lua_type(L, (n)) <= 0) + +#define lua_pushliteral(L, s) lua_pushstring(L, "" s) + +#define lua_pushglobaltable(L) \ + ((void)lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)) + +#define lua_tostring(L,i) lua_tolstring(L, (i), NULL) + + +#define lua_insert(L,idx) lua_rotate(L, (idx), 1) + +#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1)) + +#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1)) + +/* }============================================================== */ + + +/* +** {============================================================== +** compatibility macros +** =============================================================== +*/ +#if defined(LUA_COMPAT_APIINTCASTS) + +#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n)) +#define lua_tounsignedx(L,i,is) ((lua_Unsigned)lua_tointegerx(L,i,is)) +#define lua_tounsigned(L,i) lua_tounsignedx(L,(i),NULL) + +#endif + +#define lua_newuserdata(L,s) lua_newuserdatauv(L,s,1) +#define lua_getuservalue(L,idx) lua_getiuservalue(L,idx,1) +#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1) + +#define LUA_NUMTAGS LUA_NUMTYPES + +/* }============================================================== */ + +/* +** {====================================================================== +** Debug API +** ======================================================================= +*/ + + +/* +** Event codes +*/ +#define LUA_HOOKCALL 0 +#define LUA_HOOKRET 1 +#define LUA_HOOKLINE 2 +#define LUA_HOOKCOUNT 3 +#define LUA_HOOKTAILCALL 4 + + +/* +** Event masks +*/ +#define LUA_MASKCALL (1 << LUA_HOOKCALL) +#define LUA_MASKRET (1 << LUA_HOOKRET) +#define LUA_MASKLINE (1 << LUA_HOOKLINE) +#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT) + +typedef struct lua_Debug lua_Debug; /* activation record */ + + +/* Functions to be called by the debugger in specific events */ +typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar); + + +LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar); +LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar); +LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n); +LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n); +LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n); + +LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); +LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1, + int fidx2, int n2); + +LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count); +LUA_API lua_Hook (lua_gethook) (lua_State *L); +LUA_API int (lua_gethookmask) (lua_State *L); +LUA_API int (lua_gethookcount) (lua_State *L); + +LUA_API int (lua_setcstacklimit) (lua_State *L, unsigned int limit); + +struct lua_Debug { + int event; + const char *name; /* (n) */ + const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */ + const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */ + const char *source; /* (S) */ + size_t srclen; /* (S) */ + int currentline; /* (l) */ + int linedefined; /* (S) */ + int lastlinedefined; /* (S) */ + unsigned char nups; /* (u) number of upvalues */ + unsigned char nparams;/* (u) number of parameters */ + char isvararg; /* (u) */ + char istailcall; /* (t) */ + unsigned short ftransfer; /* (r) index of first value transferred */ + unsigned short ntransfer; /* (r) number of transferred values */ + char short_src[LUA_IDSIZE]; /* (S) */ + /* private part */ + struct CallInfo *i_ci; /* active function */ +}; + +/* }====================================================================== */ + + +/****************************************************************************** +* Copyright (C) 1994-2021 Lua.org, PUC-Rio. +* +* Permission is hereby granted, free of charge, to any person obtaining +* a copy of this software and associated documentation files (the +* "Software"), to deal in the Software without restriction, including +* without limitation the rights to use, copy, modify, merge, publish, +* distribute, sublicense, and/or sell copies of the Software, and to +* permit persons to whom the Software is furnished to do so, subject to +* the following conditions: +* +* The above copyright notice and this permission notice shall be +* included in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +******************************************************************************/ + + +#endif diff --git a/include/lua/lua.hpp b/include/lua/lua.hpp new file mode 100644 index 0000000..ec417f5 --- /dev/null +++ b/include/lua/lua.hpp @@ -0,0 +1,9 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} diff --git a/include/lua/luaconf.h b/include/lua/luaconf.h new file mode 100644 index 0000000..e64d2ee --- /dev/null +++ b/include/lua/luaconf.h @@ -0,0 +1,790 @@ +/* +** $Id: luaconf.h $ +** Configuration file for Lua +** See Copyright Notice in lua.h +*/ + + +#ifndef luaconf_h +#define luaconf_h + +#include +#include + + +/* +** =================================================================== +** General Configuration File for Lua +** +** Some definitions here can be changed externally, through the compiler +** (e.g., with '-D' options): They are commented out or protected +** by '#if !defined' guards. However, several other definitions +** should be changed directly here, either because they affect the +** Lua ABI (by making the changes here, you ensure that all software +** connected to Lua, such as C libraries, will be compiled with the same +** configuration); or because they are seldom changed. +** +** Search for "@@" to find all configurable definitions. +** =================================================================== +*/ + + +/* +** {==================================================================== +** System Configuration: macros to adapt (if needed) Lua to some +** particular platform, for instance restricting it to C89. +** ===================================================================== +*/ + +/* +@@ LUA_USE_C89 controls the use of non-ISO-C89 features. +** Define it if you want Lua to avoid the use of a few C99 features +** or Windows-specific features on Windows. +*/ +/* #define LUA_USE_C89 */ + + +/* +** By default, Lua on Windows use (some) specific Windows features +*/ +#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE) +#define LUA_USE_WINDOWS /* enable goodies for regular Windows */ +#endif + + +#if defined(LUA_USE_WINDOWS) +#define LUA_DL_DLL /* enable support for DLL */ +#define LUA_USE_C89 /* broadly, Windows is C89 */ +#endif + + +#if defined(LUA_USE_LINUX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* needs an extra library: -ldl */ +#endif + + +#if defined(LUA_USE_MACOSX) +#define LUA_USE_POSIX +#define LUA_USE_DLOPEN /* MacOS does not need -ldl */ +#endif + + +/* +@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits. +*/ +#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3) + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Number types. These options should not be +** set externally, because any other code connected to Lua must +** use the same configuration. +** =================================================================== +*/ + +/* +@@ LUA_INT_TYPE defines the type for Lua integers. +@@ LUA_FLOAT_TYPE defines the type for Lua floats. +** Lua should work fine with any mix of these options supported +** by your C compiler. The usual configurations are 64-bit integers +** and 'double' (the default), 32-bit integers and 'float' (for +** restricted platforms), and 'long'/'double' (for C compilers not +** compliant with C99, which may not have support for 'long long'). +*/ + +/* predefined options for LUA_INT_TYPE */ +#define LUA_INT_INT 1 +#define LUA_INT_LONG 2 +#define LUA_INT_LONGLONG 3 + +/* predefined options for LUA_FLOAT_TYPE */ +#define LUA_FLOAT_FLOAT 1 +#define LUA_FLOAT_DOUBLE 2 +#define LUA_FLOAT_LONGDOUBLE 3 + + +/* Default configuration ('long long' and 'double', for 64-bit Lua) */ +#define LUA_INT_DEFAULT LUA_INT_LONGLONG +#define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE + + +/* +@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats. +*/ +#define LUA_32BITS 0 + + +/* +@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for +** C89 ('long' and 'double'); Windows always has '__int64', so it does +** not need to use this case. +*/ +#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS) +#define LUA_C89_NUMBERS 1 +#else +#define LUA_C89_NUMBERS 0 +#endif + + +#if LUA_32BITS /* { */ +/* +** 32-bit integers and 'float' +*/ +#if LUAI_IS32INT /* use 'int' if big enough */ +#define LUA_INT_TYPE LUA_INT_INT +#else /* otherwise use 'long' */ +#define LUA_INT_TYPE LUA_INT_LONG +#endif +#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT + +#elif LUA_C89_NUMBERS /* }{ */ +/* +** largest types available for C89 ('long' and 'double') +*/ +#define LUA_INT_TYPE LUA_INT_LONG +#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE + +#else /* }{ */ +/* use defaults */ + +#define LUA_INT_TYPE LUA_INT_DEFAULT +#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT + +#endif /* } */ + + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Paths. +** =================================================================== +*/ + +/* +** LUA_PATH_SEP is the character that separates templates in a path. +** LUA_PATH_MARK is the string that marks the substitution points in a +** template. +** LUA_EXEC_DIR in a Windows path is replaced by the executable's +** directory. +*/ +#define LUA_PATH_SEP ";" +#define LUA_PATH_MARK "?" +#define LUA_EXEC_DIR "!" + + +/* +@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for +** Lua libraries. +@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for +** C libraries. +** CHANGE them if your machine has a non-conventional directory +** hierarchy or if you want to install your libraries in +** non-conventional directories. +*/ + +#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR +#if defined(_WIN32) /* { */ +/* +** In Windows, any exclamation mark ('!') in the path is replaced by the +** path of the directory of the executable file of the current process. +*/ +#define LUA_LDIR "!\\lua\\" +#define LUA_CDIR "!\\" +#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \ + LUA_SHRDIR"?.lua;" LUA_SHRDIR"?\\init.lua;" \ + ".\\?.lua;" ".\\?\\init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.dll;" \ + LUA_CDIR"..\\lib\\lua\\" LUA_VDIR "\\?.dll;" \ + LUA_CDIR"loadall.dll;" ".\\?.dll" +#endif + +#else /* }{ */ + +#define LUA_ROOT "/usr/local/" +#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/" +#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR "/" + +#if !defined(LUA_PATH_DEFAULT) +#define LUA_PATH_DEFAULT \ + LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \ + LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \ + "./?.lua;" "./?/init.lua" +#endif + +#if !defined(LUA_CPATH_DEFAULT) +#define LUA_CPATH_DEFAULT \ + LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so" +#endif + +#endif /* } */ + + +/* +@@ LUA_DIRSEP is the directory separator (for submodules). +** CHANGE it if your machine does not use "/" as the directory separator +** and is not Windows. (On Windows Lua automatically uses "\".) +*/ +#if !defined(LUA_DIRSEP) + +#if defined(_WIN32) +#define LUA_DIRSEP "\\" +#else +#define LUA_DIRSEP "/" +#endif + +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Marks for exported symbols in the C code +** =================================================================== +*/ + +/* +@@ LUA_API is a mark for all core API functions. +@@ LUALIB_API is a mark for all auxiliary library functions. +@@ LUAMOD_API is a mark for all standard library opening functions. +** CHANGE them if you need to define those functions in some special way. +** For instance, if you want to create one Windows DLL with the core and +** the libraries, you may want to use the following definition (define +** LUA_BUILD_AS_DLL to get it). +*/ +#if defined(LUA_BUILD_AS_DLL) /* { */ + +#if defined(LUA_CORE) || defined(LUA_LIB) /* { */ +#define LUA_API __declspec(dllexport) +#else /* }{ */ +#define LUA_API __declspec(dllimport) +#endif /* } */ + +#else /* }{ */ + +#define LUA_API extern + +#endif /* } */ + + +/* +** More often than not the libs go together with the core. +*/ +#define LUALIB_API LUA_API +#define LUAMOD_API LUA_API + + +/* +@@ LUAI_FUNC is a mark for all extern functions that are not to be +** exported to outside modules. +@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables, +** none of which to be exported to outside modules (LUAI_DDEF for +** definitions and LUAI_DDEC for declarations). +** CHANGE them if you need to mark them in some special way. Elf/gcc +** (versions 3.2 and later) mark them as "hidden" to optimize access +** when Lua is compiled as a shared library. Not all elf targets support +** this attribute. Unfortunately, gcc does not offer a way to check +** whether the target offers that support, and those without support +** give a warning about it. To avoid these warnings, change to the +** default definition. +*/ +#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \ + defined(__ELF__) /* { */ +#define LUAI_FUNC __attribute__((visibility("internal"))) extern +#else /* }{ */ +#define LUAI_FUNC extern +#endif /* } */ + +#define LUAI_DDEC(dec) LUAI_FUNC dec +#define LUAI_DDEF /* empty */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Compatibility with previous versions +** =================================================================== +*/ + +/* +@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3. +** You can define it to get all options, or change specific options +** to fit your specific needs. +*/ +#if defined(LUA_COMPAT_5_3) /* { */ + +/* +@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated +** functions in the mathematical library. +** (These functions were already officially removed in 5.3; +** nevertheless they are still available here.) +*/ +#define LUA_COMPAT_MATHLIB + +/* +@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for +** manipulating other integer types (lua_pushunsigned, lua_tounsigned, +** luaL_checkint, luaL_checklong, etc.) +** (These macros were also officially removed in 5.3, but they are still +** available here.) +*/ +#define LUA_COMPAT_APIINTCASTS + + +/* +@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod +** using '__lt'. +*/ +#define LUA_COMPAT_LT_LE + + +/* +@@ The following macros supply trivial compatibility for some +** changes in the API. The macros themselves document how to +** change your code to avoid using them. +** (Once more, these macros were officially removed in 5.3, but they are +** still available here.) +*/ +#define lua_strlen(L,i) lua_rawlen(L, (i)) + +#define lua_objlen(L,i) lua_rawlen(L, (i)) + +#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ) +#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT) + +#endif /* } */ + +/* }================================================================== */ + + + +/* +** {================================================================== +** Configuration for Numbers (low-level part). +** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_* +** satisfy your needs. +** =================================================================== +*/ + +/* +@@ LUAI_UACNUMBER is the result of a 'default argument promotion' +@@ over a floating number. +@@ l_floatatt(x) corrects float attribute 'x' to the proper float type +** by prefixing it with one of FLT/DBL/LDBL. +@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats. +@@ LUA_NUMBER_FMT is the format for writing floats. +@@ lua_number2str converts a float to a string. +@@ l_mathop allows the addition of an 'l' or 'f' to all math operations. +@@ l_floor takes the floor of a float. +@@ lua_str2number converts a decimal numeral to a number. +*/ + + +/* The following definitions are good for most cases here */ + +#define l_floor(x) (l_mathop(floor)(x)) + +#define lua_number2str(s,sz,n) \ + l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n)) + +/* +@@ lua_numbertointeger converts a float number with an integral value +** to an integer, or returns 0 if float is not within the range of +** a lua_Integer. (The range comparisons are tricky because of +** rounding. The tests here assume a two-complement representation, +** where MININTEGER always has an exact representation as a float; +** MAXINTEGER may not have one, and therefore its conversion to float +** may have an ill-defined value.) +*/ +#define lua_numbertointeger(n,p) \ + ((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \ + (n) < -(LUA_NUMBER)(LUA_MININTEGER) && \ + (*(p) = (LUA_INTEGER)(n), 1)) + + +/* now the variable definitions */ + +#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */ + +#define LUA_NUMBER float + +#define l_floatatt(n) (FLT_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.7g" + +#define l_mathop(op) op##f + +#define lua_str2number(s,p) strtof((s), (p)) + + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */ + +#define LUA_NUMBER long double + +#define l_floatatt(n) (LDBL_##n) + +#define LUAI_UACNUMBER long double + +#define LUA_NUMBER_FRMLEN "L" +#define LUA_NUMBER_FMT "%.19Lg" + +#define l_mathop(op) op##l + +#define lua_str2number(s,p) strtold((s), (p)) + +#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */ + +#define LUA_NUMBER double + +#define l_floatatt(n) (DBL_##n) + +#define LUAI_UACNUMBER double + +#define LUA_NUMBER_FRMLEN "" +#define LUA_NUMBER_FMT "%.14g" + +#define l_mathop(op) op + +#define lua_str2number(s,p) strtod((s), (p)) + +#else /* }{ */ + +#error "numeric float type not defined" + +#endif /* } */ + + + +/* +@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER. +@@ LUAI_UACINT is the result of a 'default argument promotion' +@@ over a LUA_INTEGER. +@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers. +@@ LUA_INTEGER_FMT is the format for writing integers. +@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER. +@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER. +@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED. +@@ LUA_UNSIGNEDBITS is the number of bits in a LUA_UNSIGNED. +@@ lua_integer2str converts an integer to a string. +*/ + + +/* The following definitions are good for most cases here */ + +#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d" + +#define LUAI_UACINT LUA_INTEGER + +#define lua_integer2str(s,sz,n) \ + l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n)) + +/* +** use LUAI_UACINT here to avoid problems with promotions (which +** can turn a comparison between unsigneds into a signed comparison) +*/ +#define LUA_UNSIGNED unsigned LUAI_UACINT + + +#define LUA_UNSIGNEDBITS (sizeof(LUA_UNSIGNED) * CHAR_BIT) + + +/* now the variable definitions */ + +#if LUA_INT_TYPE == LUA_INT_INT /* { int */ + +#define LUA_INTEGER int +#define LUA_INTEGER_FRMLEN "" + +#define LUA_MAXINTEGER INT_MAX +#define LUA_MININTEGER INT_MIN + +#define LUA_MAXUNSIGNED UINT_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */ + +#define LUA_INTEGER long +#define LUA_INTEGER_FRMLEN "l" + +#define LUA_MAXINTEGER LONG_MAX +#define LUA_MININTEGER LONG_MIN + +#define LUA_MAXUNSIGNED ULONG_MAX + +#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */ + +/* use presence of macro LLONG_MAX as proxy for C99 compliance */ +#if defined(LLONG_MAX) /* { */ +/* use ISO C99 stuff */ + +#define LUA_INTEGER long long +#define LUA_INTEGER_FRMLEN "ll" + +#define LUA_MAXINTEGER LLONG_MAX +#define LUA_MININTEGER LLONG_MIN + +#define LUA_MAXUNSIGNED ULLONG_MAX + +#elif defined(LUA_USE_WINDOWS) /* }{ */ +/* in Windows, can use specific Windows types */ + +#define LUA_INTEGER __int64 +#define LUA_INTEGER_FRMLEN "I64" + +#define LUA_MAXINTEGER _I64_MAX +#define LUA_MININTEGER _I64_MIN + +#define LUA_MAXUNSIGNED _UI64_MAX + +#else /* }{ */ + +#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \ + or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)" + +#endif /* } */ + +#else /* }{ */ + +#error "numeric integer type not defined" + +#endif /* } */ + +/* }================================================================== */ + + +/* +** {================================================================== +** Dependencies with C99 and other C details +** =================================================================== +*/ + +/* +@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89. +** (All uses in Lua have only one format item.) +*/ +#if !defined(LUA_USE_C89) +#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i) +#else +#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i)) +#endif + + +/* +@@ lua_strx2number converts a hexadecimal numeral to a number. +** In C99, 'strtod' does that conversion. Otherwise, you can +** leave 'lua_strx2number' undefined and Lua will provide its own +** implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_strx2number(s,p) lua_str2number(s,p) +#endif + + +/* +@@ lua_pointer2str converts a pointer to a readable string in a +** non-specified way. +*/ +#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p) + + +/* +@@ lua_number2strx converts a float to a hexadecimal numeral. +** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that. +** Otherwise, you can leave 'lua_number2strx' undefined and Lua will +** provide its own implementation. +*/ +#if !defined(LUA_USE_C89) +#define lua_number2strx(L,b,sz,f,n) \ + ((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n))) +#endif + + +/* +** 'strtof' and 'opf' variants for math functions are not valid in +** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the +** availability of these variants. ('math.h' is already included in +** all files that use these macros.) +*/ +#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF)) +#undef l_mathop /* variants not available */ +#undef lua_str2number +#define l_mathop(op) (lua_Number)op /* no variant */ +#define lua_str2number(s,p) ((lua_Number)strtod((s), (p))) +#endif + + +/* +@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation +** functions. It must be a numerical type; Lua will use 'intptr_t' if +** available, otherwise it will use 'ptrdiff_t' (the nearest thing to +** 'intptr_t' in C89) +*/ +#define LUA_KCONTEXT ptrdiff_t + +#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \ + __STDC_VERSION__ >= 199901L +#include +#if defined(INTPTR_MAX) /* even in C99 this type is optional */ +#undef LUA_KCONTEXT +#define LUA_KCONTEXT intptr_t +#endif +#endif + + +/* +@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point). +** Change that if you do not want to use C locales. (Code using this +** macro must include the header 'locale.h'.) +*/ +#if !defined(lua_getlocaledecpoint) +#define lua_getlocaledecpoint() (localeconv()->decimal_point[0]) +#endif + + +/* +** macros to improve jump prediction, used mostly for error handling +** and debug facilities. (Some macros in the Lua API use these macros. +** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your +** code.) +*/ +#if !defined(luai_likely) + +#if defined(__GNUC__) && !defined(LUA_NOBUILTIN) +#define luai_likely(x) (__builtin_expect(((x) != 0), 1)) +#define luai_unlikely(x) (__builtin_expect(((x) != 0), 0)) +#else +#define luai_likely(x) (x) +#define luai_unlikely(x) (x) +#endif + +#endif + + +#if defined(LUA_CORE) || defined(LUA_LIB) +/* shorter names for Lua's own use */ +#define l_likely(x) luai_likely(x) +#define l_unlikely(x) luai_unlikely(x) +#endif + + + +/* }================================================================== */ + + +/* +** {================================================================== +** Language Variations +** ===================================================================== +*/ + +/* +@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some +** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from +** numbers to strings. Define LUA_NOCVTS2N to turn off automatic +** coercion from strings to numbers. +*/ +/* #define LUA_NOCVTN2S */ +/* #define LUA_NOCVTS2N */ + + +/* +@@ LUA_USE_APICHECK turns on several consistency checks on the C API. +** Define it as a help when debugging C code. +*/ +#if defined(LUA_USE_APICHECK) +#include +#define luai_apicheck(l,e) assert(e) +#endif + +/* }================================================================== */ + + +/* +** {================================================================== +** Macros that affect the API and must be stable (that is, must be the +** same when you compile Lua and when you compile code that links to +** Lua). +** ===================================================================== +*/ + +/* +@@ LUAI_MAXSTACK limits the size of the Lua stack. +** CHANGE it if you need a different limit. This limit is arbitrary; +** its only purpose is to stop Lua from consuming unlimited stack +** space (and to reserve some numbers for pseudo-indices). +** (It must fit into max(size_t)/32.) +*/ +#if LUAI_IS32INT +#define LUAI_MAXSTACK 1000000 +#else +#define LUAI_MAXSTACK 15000 +#endif + + +/* +@@ LUA_EXTRASPACE defines the size of a raw memory area associated with +** a Lua state with very fast access. +** CHANGE it if you need a different size. +*/ +#define LUA_EXTRASPACE (sizeof(void *)) + + +/* +@@ LUA_IDSIZE gives the maximum size for the description of the source +@@ of a function in debug information. +** CHANGE it if you want a different size. +*/ +#define LUA_IDSIZE 60 + + +/* +@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system. +*/ +#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number))) + + +/* +@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure +** maximum alignment for the other items in that union. +*/ +#define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l + +/* }================================================================== */ + + + + + +/* =================================================================== */ + +/* +** Local configuration. You can use this space to add your redefinitions +** without modifying the main part of the file. +*/ + + + + + +#endif + diff --git a/include/lua/lualib.h b/include/lua/lualib.h new file mode 100644 index 0000000..2625529 --- /dev/null +++ b/include/lua/lualib.h @@ -0,0 +1,52 @@ +/* +** $Id: lualib.h $ +** Lua standard libraries +** See Copyright Notice in lua.h +*/ + + +#ifndef lualib_h +#define lualib_h + +#include "lua.h" + + +/* version suffix for environment variable names */ +#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR + + +LUAMOD_API int (luaopen_base) (lua_State *L); + +#define LUA_COLIBNAME "coroutine" +LUAMOD_API int (luaopen_coroutine) (lua_State *L); + +#define LUA_TABLIBNAME "table" +LUAMOD_API int (luaopen_table) (lua_State *L); + +#define LUA_IOLIBNAME "io" +LUAMOD_API int (luaopen_io) (lua_State *L); + +#define LUA_OSLIBNAME "os" +LUAMOD_API int (luaopen_os) (lua_State *L); + +#define LUA_STRLIBNAME "string" +LUAMOD_API int (luaopen_string) (lua_State *L); + +#define LUA_UTF8LIBNAME "utf8" +LUAMOD_API int (luaopen_utf8) (lua_State *L); + +#define LUA_MATHLIBNAME "math" +LUAMOD_API int (luaopen_math) (lua_State *L); + +#define LUA_DBLIBNAME "debug" +LUAMOD_API int (luaopen_debug) (lua_State *L); + +#define LUA_LOADLIBNAME "package" +LUAMOD_API int (luaopen_package) (lua_State *L); + + +/* open all previous libraries */ +LUALIB_API void (luaL_openlibs) (lua_State *L); + + +#endif diff --git a/include/lua/lundump.h b/include/lua/lundump.h new file mode 100644 index 0000000..f3748a9 --- /dev/null +++ b/include/lua/lundump.h @@ -0,0 +1,36 @@ +/* +** $Id: lundump.h $ +** load precompiled Lua chunks +** See Copyright Notice in lua.h +*/ + +#ifndef lundump_h +#define lundump_h + +#include "llimits.h" +#include "lobject.h" +#include "lzio.h" + + +/* data to catch conversion errors */ +#define LUAC_DATA "\x19\x93\r\n\x1a\n" + +#define LUAC_INT 0x5678 +#define LUAC_NUM cast_num(370.5) + +/* +** Encode major-minor version in one byte, one nibble for each +*/ +#define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ +#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) + +#define LUAC_FORMAT 0 /* this is the official format */ + +/* load one chunk; from lundump.c */ +LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name); + +/* dump one chunk; from ldump.c */ +LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, + void* data, int strip); + +#endif diff --git a/include/lua/lvm.h b/include/lua/lvm.h new file mode 100644 index 0000000..1bc16f3 --- /dev/null +++ b/include/lua/lvm.h @@ -0,0 +1,136 @@ +/* +** $Id: lvm.h $ +** Lua virtual machine +** See Copyright Notice in lua.h +*/ + +#ifndef lvm_h +#define lvm_h + + +#include "ldo.h" +#include "lobject.h" +#include "ltm.h" + + +#if !defined(LUA_NOCVTN2S) +#define cvt2str(o) ttisnumber(o) +#else +#define cvt2str(o) 0 /* no conversion from numbers to strings */ +#endif + + +#if !defined(LUA_NOCVTS2N) +#define cvt2num(o) ttisstring(o) +#else +#define cvt2num(o) 0 /* no conversion from strings to numbers */ +#endif + + +/* +** You can define LUA_FLOORN2I if you want to convert floats to integers +** by flooring them (instead of raising an error if they are not +** integral values) +*/ +#if !defined(LUA_FLOORN2I) +#define LUA_FLOORN2I F2Ieq +#endif + + +/* +** Rounding modes for float->integer coercion + */ +typedef enum { + F2Ieq, /* no rounding; accepts only integral values */ + F2Ifloor, /* takes the floor of the number */ + F2Iceil /* takes the ceil of the number */ +} F2Imod; + + +/* convert an object to a float (including string coercion) */ +#define tonumber(o,n) \ + (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n)) + + +/* convert an object to a float (without string coercion) */ +#define tonumberns(o,n) \ + (ttisfloat(o) ? ((n) = fltvalue(o), 1) : \ + (ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0)) + + +/* convert an object to an integer (including string coercion) */ +#define tointeger(o,i) \ + (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ + : luaV_tointeger(o,i,LUA_FLOORN2I)) + + +/* convert an object to an integer (without string coercion) */ +#define tointegerns(o,i) \ + (l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \ + : luaV_tointegerns(o,i,LUA_FLOORN2I)) + + +#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2)) + +#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2) + + +/* +** fast track for 'gettable': if 't' is a table and 't[k]' is present, +** return 1 with 'slot' pointing to 't[k]' (position of final result). +** Otherwise, return 0 (meaning it will have to check metamethod) +** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL +** (otherwise). 'f' is the raw get function to use. +*/ +#define luaV_fastget(L,t,k,slot,f) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = f(hvalue(t), k), /* else, do raw access */ \ + !isempty(slot))) /* result not empty? */ + + +/* +** Special case of 'luaV_fastget' for integers, inlining the fast case +** of 'luaH_getint'. +*/ +#define luaV_fastgeti(L,t,k,slot) \ + (!ttistable(t) \ + ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \ + : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \ + ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \ + !isempty(slot))) /* result not empty? */ + + +/* +** Finish a fast set operation (when fast get succeeds). In that case, +** 'slot' points to the place to put the value. +*/ +#define luaV_finishfastset(L,t,slot,v) \ + { setobj2t(L, cast(TValue *,slot), v); \ + luaC_barrierback(L, gcvalue(t), v); } + + + + +LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); +LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); +LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n); +LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); +LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, + F2Imod mode); +LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); +LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, + StkId val, const TValue *slot); +LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, + TValue *val, const TValue *slot); +LUAI_FUNC void luaV_finishOp (lua_State *L); +LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); +LUAI_FUNC void luaV_concat (lua_State *L, int total); +LUAI_FUNC lua_Integer luaV_idiv (lua_State *L, lua_Integer x, lua_Integer y); +LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y); +LUAI_FUNC lua_Number luaV_modf (lua_State *L, lua_Number x, lua_Number y); +LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y); +LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb); + +#endif diff --git a/include/lua/lzio.h b/include/lua/lzio.h new file mode 100644 index 0000000..38f397f --- /dev/null +++ b/include/lua/lzio.h @@ -0,0 +1,66 @@ +/* +** $Id: lzio.h $ +** Buffered streams +** See Copyright Notice in lua.h +*/ + + +#ifndef lzio_h +#define lzio_h + +#include "lua.h" + +#include "lmem.h" + + +#define EOZ (-1) /* end of stream */ + +typedef struct Zio ZIO; + +#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z)) + + +typedef struct Mbuffer { + char *buffer; + size_t n; + size_t buffsize; +} Mbuffer; + +#define luaZ_initbuffer(L, buff) ((buff)->buffer = NULL, (buff)->buffsize = 0) + +#define luaZ_buffer(buff) ((buff)->buffer) +#define luaZ_sizebuffer(buff) ((buff)->buffsize) +#define luaZ_bufflen(buff) ((buff)->n) + +#define luaZ_buffremove(buff,i) ((buff)->n -= (i)) +#define luaZ_resetbuffer(buff) ((buff)->n = 0) + + +#define luaZ_resizebuffer(L, buff, size) \ + ((buff)->buffer = luaM_reallocvchar(L, (buff)->buffer, \ + (buff)->buffsize, size), \ + (buff)->buffsize = size) + +#define luaZ_freebuffer(L, buff) luaZ_resizebuffer(L, buff, 0) + + +LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, + void *data); +LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */ + + + +/* --------- Private Part ------------------ */ + +struct Zio { + size_t n; /* bytes still unread */ + const char *p; /* current position in buffer */ + lua_Reader reader; /* reader function */ + void *data; /* additional data */ + lua_State *L; /* Lua state (for reader) */ +}; + + +LUAI_FUNC int luaZ_fill (ZIO *z); + +#endif diff --git a/include/sol2/config.hpp b/include/sol2/config.hpp new file mode 100644 index 0000000..18c138d --- /dev/null +++ b/include/sol2/config.hpp @@ -0,0 +1,53 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This file was generated with a script. +// Generated 2020-10-03 21:34:25.034794 UTC +// This header was generated with sol v3.2.1 (revision 48eea7b5) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_CONFIG_HPP +#define SOL_SINGLE_CONFIG_HPP + +// beginning of sol/config.hpp + +/* Base, empty configuration file! + + To override, place a file in your include paths of the form: + +. (your include path here) +| sol (directory, or equivalent) + | config.hpp (your config.hpp file) + + So that when sol2 includes the file + +#include + + it gives you the configuration values you desire. Configuration values can be +seen in the safety.rst of the doc/src, or at +https://sol2.readthedocs.io/en/latest/safety.html ! You can also pass them through +the build system, or the command line options of your compiler. + +*/ + +// end of sol/config.hpp + +#endif // SOL_SINGLE_CONFIG_HPP \ No newline at end of file diff --git a/include/sol2/forward.hpp b/include/sol2/forward.hpp new file mode 100644 index 0000000..afd6fae --- /dev/null +++ b/include/sol2/forward.hpp @@ -0,0 +1,828 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This file was generated with a script. +// Generated 2020-10-03 21:34:25.022965 UTC +// This header was generated with sol v3.2.1 (revision 48eea7b5) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_INCLUDE_FORWARD_HPP +#define SOL_SINGLE_INCLUDE_FORWARD_HPP + +// beginning of sol/forward.hpp + +#ifndef SOL_FORWARD_HPP +#define SOL_FORWARD_HPP + +// beginning of sol/version.hpp + +#include "config.hpp" + +#include + +#define SOL_VERSION_MAJOR 3 +#define SOL_VERSION_MINOR 5 +#define SOL_VERSION_PATCH 0 +#define SOL_VERSION_STRING "3.5.0" +#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH)) + +#define SOL_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0) +#define SOL_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0) +#define SOL_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3) +#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0) + +#define SOL_ON | +#define SOL_OFF ^ +#define SOL_DEFAULT_ON + +#define SOL_DEFAULT_OFF - + +#if defined(_MSC_VER) +#define SOL_COMPILER_CLANG_I_ SOL_OFF +#define SOL_COMPILER_GCC_I_ SOL_OFF +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_ON +#elif defined(__clang__) +#define SOL_COMPILER_CLANG_I_ SOL_ON +#define SOL_COMPILER_GCC_I_ SOL_OFF +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_OFF +#elif defined(__GNUC__) +#define SOL_COMPILER_CLANG_I_ SOL_OFF +#define SOL_COMPILER_GCC_I_ SOL_ON +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_OFF +#else +#define SOL_COMPILER_CLANG_I_ SOL_OFF +#define SOL_COMPILER_GCC_I_ SOL_OFF +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_OFF +#endif + +#if defined(__MINGW32__) +#define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_ON +#else +#define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_OFF +#endif + +#if SIZE_MAX <= 0xFFFFULL +#define SOL_PLATFORM_X16_I_ SOL_ON +#define SOL_PLATFORM_X86_I_ SOL_OFF +#define SOL_PLATFORM_X64_I_ SOL_OFF +#elif SIZE_MAX <= 0xFFFFFFFFULL +#define SOL_PLATFORM_X16_I_ SOL_OFF +#define SOL_PLATFORM_X86_I_ SOL_ON +#define SOL_PLATFORM_X64_I_ SOL_OFF +#else +#define SOL_PLATFORM_X16_I_ SOL_OFF +#define SOL_PLATFORM_X86_I_ SOL_OFF +#define SOL_PLATFORM_X64_I_ SOL_ON +#endif + +#define SOL_PLATFORM_ARM32_I_ SOL_OFF +#define SOL_PLATFORM_ARM64_I_ SOL_OFF + +#if defined(_WIN32) +#define SOL_PLATFORM_WINDOWS_I_ SOL_ON +#else +#define SOL_PLATFORM_WINDOWS_I_ SOL_OFF +#endif +#if defined(__APPLE__) +#define SOL_PLATFORM_APPLE_I_ SOL_ON +#else +#define SOL_PLATFORM_APPLE_I_ SOL_OFF +#endif +#if defined(__unix__) +#define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON +#else +#define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF +#endif +#if defined(__linux__) +#define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON +#else +#define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF +#endif + +#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF +#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF + +#if defined(SOL_IN_DEBUG_DETECTED) +#if SOL_IN_DEBUG_DETECTED != 0 +#define SOL_DEBUG_BUILD_I_ SOL_ON +#else +#define SOL_DEBUG_BUILD_I_ SOL_OFF +#endif +#elif !defined(NDEBUG) +#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && defined(_DEBUG) +#define SOL_DEBUG_BUILD_I_ SOL_ON +#elif (SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)) && !defined(__OPTIMIZE__) +#define SOL_DEBUG_BUILD_I_ SOL_ON +#else +#define SOL_DEBUG_BUILD_I_ SOL_OFF +#endif +#else +#define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF +#endif // We are in a debug mode of some sort + +#if defined(SOL_NO_EXCEPTIONS) +#if (SOL_NO_EXCEPTIONS != 0) +#define SOL_EXCEPTIONS_I_ SOL_OFF +#else +#define SOL_EXCEPTIONS_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) +#if !defined(_CPPUNWIND) +#define SOL_EXCEPTIONS_I_ SOL_OFF +#else +#define SOL_EXCEPTIONS_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_) +#if !defined(__EXCEPTIONS) +#define SOL_EXCEPTIONS_I_ SOL_OFF +#else +#define SOL_EXCEPTIONS_I_ SOL_ON +#endif +#else +#define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_RTTI) +#if (SOL_NO_RTTI != 0) +#define SOL_RTTI_I_ SOL_OFF +#else +#define SOL_RTTI_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) +#if !defined(_CPPRTTI) +#define SOL_RTTI_I_ SOL_OFF +#else +#define SOL_RTTI_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_) +#if !defined(__GXX_RTTI) +#define SOL_RTTI_I_ SOL_OFF +#else +#define SOL_RTTI_I_ SOL_ON +#endif +#else +#define SOL_RTTI_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_THREAD_LOCAL) && (SOL_NO_THREAD_LOCAL != 0) +#define SOL_USE_THREAD_LOCAL_I_ SOL_OFF +#else +#define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON +#endif // thread_local keyword is bjorked on some platforms + +#if defined(SOL_ALL_SAFETIES_ON) && (SOL_ALL_SAFETIES_ON != 0) +#define SOL_ALL_SAFETIES_ON_I_ SOL_ON +#else +#define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_GETTER) && (SOL_SAFE_GETTER != 0) +#define SOL_SAFE_GETTER_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_GETTER_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_USERTYPE) && (SOL_SAFE_USERTYPE != 0) +#define SOL_SAFE_USERTYPE_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_USERTYPE_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_REFERENCES) && (SOL_SAFE_REFERENCES != 0) +#define SOL_SAFE_REFERENCES_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_REFERENCES_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if (defined(SOL_SAFE_FUNCTIONS) && (SOL_SAFE_FUNCTIONS != 0)) \ + || (defined(SOL_SAFE_FUNCTION_OBJECTS) && (SOL_SAFE_FUNCTION_OBJECTS != 0)) +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_FUNCTION_CALLS) && (SOL_SAFE_FUNCTION_CALLS != 0) +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_PROXIES) && (SOL_SAFE_PROXIES != 0) +#define SOL_SAFE_PROXIES_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_PROXIES_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_NUMERICS) && (SOL_SAFE_NUMERICS != 0) +#define SOL_SAFE_NUMERICS_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_NUMERICS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_STACK_CHECK) && (SOL_SAFE_STACK_CHECK != 0) +#define SOL_SAFE_STACK_CHECK_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_STACK_CHECK_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if (defined(SOL_NO_CHECK_NUMBER_PRECISION) && (SOL_NO_CHECK_NUMBER_PRECISION != 0)) \ + || (defined(SOL_NO_CHECKING_NUMBER_PRECISION) && (SOL_NO_CHECKING_NUMBER_PRECISION != 0)) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON +#elif SOL_IS_ON(SOL_SAFE_NUMERICS_I_) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON +#else +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_STRINGS_ARE_NUMBERS) +#if (SOL_STRINGS_ARE_NUMBERS != 0) +#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON +#else +#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF +#endif +#else +#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ENABLE_INTEROP) && (SOL_ENABLE_INTEROP != 0) \ + || defined(SOL_USE_INTEROP) && (SOL_USE_INTEROP != 0) +#define SOL_USE_INTEROP_I_ SOL_ON +#else +#define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_NIL) +#if (SOL_NO_NIL != 0) +#define SOL_NIL_I_ SOL_OFF +#else +#define SOL_NIL_I_ SOL_ON +#endif +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil) +#define SOL_NIL_I_ SOL_DEFAULT_OFF +#else +#define SOL_NIL_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USERTYPE_TYPE_BINDING_INFO) +#if (SOL_USERTYPE_TYPE_BINDING_INFO != 0) +#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON +#else +#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF +#endif +#else +#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON +#endif // We should generate a my_type.__type table with lots of class information for usertypes + +#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT) +#if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0) +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON +#else +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF +#endif +#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES) +#if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0) +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON +#else +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF +#endif +#else +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON +#endif // make is_automagical on/off by default + +#if defined(SOL_STD_VARIANT) +#if (SOL_STD_VARIANT != 0) +#define SOL_STD_VARIANT_I_ SOL_ON +#else +#define SOL_STD_VARIANT_I_ SOL_OFF +#endif +#else +#if SOL_IS_ON(SOL_COMPILER_CLANG_I_) && SOL_IS_ON(SOL_PLATFORM_APPLE_I_) +#if defined(__has_include) +#if __has_include() +#define SOL_STD_VARIANT_I_ SOL_ON +#else +#define SOL_STD_VARIANT_I_ SOL_OFF +#endif +#else +#define SOL_STD_VARIANT_I_ SOL_OFF +#endif +#else +#define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON +#endif +#endif // make is_automagical on/off by default + +#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) +#if (SOL_NOEXCEPT_FUNCTION_TYPE != 0) +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON +#else +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF +#endif +#else +#if defined(__cpp_noexcept_function_type) +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L)) + // There is a bug in the VC++ compiler?? + // on /std:c++latest under x86 conditions (VS 15.5.2), + // compiler errors are tossed for noexcept markings being on function types + // that are identical in every other way to their non-noexcept marked types function types... + // VS 2019: There is absolutely a bug. +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF +#else +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON +#endif +#endif // noexcept is part of a function's type + +#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0 +#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE +#else +#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024 +#endif + +#if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 +#define SOL_ID_SIZE_I_ SOL_ID_SIZE +#else +#define SOL_ID_SIZE_I_ 512 +#endif + +#if defined(LUA_IDSIZE) && LUA_IDSIZE > 0 +#define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE +#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 +#define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE +#else +#define SOL_FILE_ID_SIZE_I_ 2048 +#endif + +#if defined(SOL_PRINT_ERRORS) +#if (SOL_PRINT_ERRORS != 0) +#define SOL_PRINT_ERRORS_I_ SOL_ON +#else +#define SOL_PRINT_ERRORS_I_ SOL_OFF +#endif +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_PRINT_ERRORS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON +#else +#define SOL_PRINT_ERRORS_I_ SOL_OFF +#endif +#endif + +#if defined(SOL_DEFAULT_PASS_ON_ERROR) && (SOL_DEFAULT_PASS_ON_ERROR != 0) +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_ON +#else +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF +#endif +#endif + +#if defined(SOL_USING_CXX_LUA) +#if (SOL_USING_CXX_LUA != 0) +#define SOL_USE_CXX_LUA_I_ SOL_ON +#else +#define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif +#elif defined(SOL_USE_CXX_LUA) +#if (SOL_USE_CXX_LUA != 0) +#define SOL_USE_CXX_LUA_I_ SOL_ON +#else +#define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif +#else +#define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif + +#if defined(SOL_USING_CXX_LUAJIT) +#if (SOL_USING_CXX_LUA != 0) +#define SOL_USE_CXX_LUAJIT_I_ SOL_ON +#else +#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif +#elif defined(SOL_USE_CXX_LUAJIT) +#if (SOL_USE_CXX_LUA != 0) +#define SOL_USE_CXX_LUAJIT_I_ SOL_ON +#else +#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif +#else +#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif + +#if defined(SOL_NO_LUA_HPP) +#if (SOL_NO_LUA_HPP != 0) +#define SOL_USE_LUA_HPP_I_ SOL_OFF +#else +#define SOL_USE_LUA_HPP_I_ SOL_ON +#endif +#elif defined(SOL_USING_CXX_LUA) +#define SOL_USE_LUA_HPP_I_ SOL_OFF +#elif defined(__has_include) +#if __has_include() +#define SOL_USE_LUA_HPP_I_ SOL_ON +#else +#define SOL_USE_LUA_HPP_I_ SOL_OFF +#endif +#else +#define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_CONTAINERS_START) +#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START +#elif defined(SOL_CONTAINERS_START_INDEX) +#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX +#elif defined(SOL_CONTAINER_START_INDEX) +#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX +#else +#define SOL_CONTAINER_START_INDEX_I_ 1 +#endif + +#if defined (SOL_NO_MEMORY_ALIGNMENT) +#if (SOL_NO_MEMORY_ALIGNMENT != 0) +#define SOL_ALIGN_MEMORY_I_ SOL_OFF +#else +#define SOL_ALIGN_MEMORY_I_ SOL_ON +#endif +#else +#define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USE_BOOST) +#if (SOL_USE_BOOST != 0) +#define SOL_USE_BOOST_I_ SOL_ON +#else +#define SOL_USE_BOOST_I_ SOL_OFF +#endif +#else +#define SOL_USE_BOOST_I_ SOL_OFF +#endif + +#if defined(SOL_USE_UNSAFE_BASE_LOOKUP) +#if (SOL_USE_UNSAFE_BASE_LOOKUP != 0) +#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON +#else +#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF +#endif +#else +#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF +#endif + +#if defined(SOL_INSIDE_UNREAL) +#if (SOL_INSIDE_UNREAL != 0) +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON +#else +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF +#endif +#else +#if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER) +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON +#else +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_NO_COMPAT) +#if (SOL_NO_COMPAT != 0) +#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF +#else +#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON +#endif +#else +#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE) +#if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0) +#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON +#else +#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF +#endif +#else +#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF +#endif + +#if SOL_IS_ON(SOL_COMPILER_FRONTEND_MINGW_I_) && defined(__GNUC__) && (__GNUC__ < 6) + // MinGW is off its rocker in some places... +#define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON +#else +#define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF +#endif + +// end of sol/version.hpp + +#include +#include +#include + +#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) +struct lua_State; +#else +extern "C" { + struct lua_State; +} +#endif // C++ Mangling for Lua vs. Not + +namespace sol { + + enum class type; + + class stateless_reference; + template + class basic_reference; + using reference = basic_reference; + using main_reference = basic_reference; + class stateless_stack_reference; + class stack_reference; + + template + class basic_bytecode; + + struct lua_value; + + struct proxy_base_tag; + template + struct proxy_base; + template + struct table_proxy; + + template + class basic_table_core; + template + using table_core = basic_table_core; + template + using main_table_core = basic_table_core; + template + using stack_table_core = basic_table_core; + template + using basic_table = basic_table_core; + using table = table_core; + using global_table = table_core; + using main_table = main_table_core; + using main_global_table = main_table_core; + using stack_table = stack_table_core; + using stack_global_table = stack_table_core; + + template + struct basic_lua_table; + using lua_table = basic_lua_table; + using stack_lua_table = basic_lua_table; + + template + class basic_usertype; + template + using usertype = basic_usertype; + template + using stack_usertype = basic_usertype; + + template + class basic_metatable; + using metatable = basic_metatable; + using stack_metatable = basic_metatable; + + template + struct basic_environment; + using environment = basic_environment; + using main_environment = basic_environment; + using stack_environment = basic_environment; + + template + class basic_function; + template + class basic_protected_function; + using unsafe_function = basic_function; + using safe_function = basic_protected_function; + using main_unsafe_function = basic_function; + using main_safe_function = basic_protected_function; + using stack_unsafe_function = basic_function; + using stack_safe_function = basic_protected_function; + using stack_aligned_unsafe_function = basic_function; + using stack_aligned_safe_function = basic_protected_function; + using protected_function = safe_function; + using main_protected_function = main_safe_function; + using stack_protected_function = stack_safe_function; + using stack_aligned_protected_function = stack_aligned_safe_function; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) + using function = protected_function; + using main_function = main_protected_function; + using stack_function = stack_protected_function; + using stack_aligned_function = stack_aligned_safe_function; +#else + using function = unsafe_function; + using main_function = main_unsafe_function; + using stack_function = stack_unsafe_function; + using stack_aligned_function = stack_aligned_unsafe_function; +#endif + using stack_aligned_stack_handler_function = basic_protected_function; + + struct unsafe_function_result; + struct protected_function_result; + using safe_function_result = protected_function_result; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) + using function_result = safe_function_result; +#else + using function_result = unsafe_function_result; +#endif + + template + class basic_object_base; + template + class basic_object; + template + class basic_userdata; + template + class basic_lightuserdata; + template + class basic_coroutine; + template + class basic_thread; + + using object = basic_object; + using userdata = basic_userdata; + using lightuserdata = basic_lightuserdata; + using thread = basic_thread; + using coroutine = basic_coroutine; + using main_object = basic_object; + using main_userdata = basic_userdata; + using main_lightuserdata = basic_lightuserdata; + using main_coroutine = basic_coroutine; + using stack_object = basic_object; + using stack_userdata = basic_userdata; + using stack_lightuserdata = basic_lightuserdata; + using stack_thread = basic_thread; + using stack_coroutine = basic_coroutine; + + struct stack_proxy_base; + struct stack_proxy; + struct variadic_args; + struct variadic_results; + struct stack_count; + struct this_state; + struct this_main_state; + struct this_environment; + + class state_view; + class state; + + template + struct as_table_t; + template + struct as_container_t; + template + struct nested; + template + struct light; + template + struct user; + template + struct as_args_t; + template + struct protect_t; + template + struct policy_wrapper; + + template + struct usertype_traits; + template + struct unique_usertype_traits; + + template + struct types { + typedef std::make_index_sequence indices; + static constexpr std::size_t size() { + return sizeof...(Args); + } + }; + + template + struct derive : std::false_type { + typedef types<> type; + }; + + template + struct base : std::false_type { + typedef types<> type; + }; + + template + struct weak_derive { + static bool value; + }; + + template + bool weak_derive::value = false; + + namespace stack { + struct record; + } + +#if SOL_IS_OFF(SOL_USE_BOOST_I_) + template + class optional; + + template + class optional; +#endif + + using check_handler_type = int(lua_State*, int, type, type, const char*); + +} // namespace sol + +#define SOL_BASE_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct base : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() +#define SOL_DERIVED_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct derive : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() + +#endif // SOL_FORWARD_HPP +// end of sol/forward.hpp + +#endif // SOL_SINGLE_INCLUDE_FORWARD_HPP \ No newline at end of file diff --git a/include/sol2/sol.hpp b/include/sol2/sol.hpp new file mode 100644 index 0000000..b1ca0f8 --- /dev/null +++ b/include/sol2/sol.hpp @@ -0,0 +1,26710 @@ +// The MIT License (MIT) + +// Copyright (c) 2013-2020 Rapptz, ThePhD and contributors + +// Permission is hereby granted, free of charge, to any person obtaining a copy of +// this software and associated documentation files (the "Software"), to deal in +// the Software without restriction, including without limitation the rights to +// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +// the Software, and to permit persons to whom the Software is furnished to do so, +// subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +// FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +// COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +// IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +// This file was generated with a script. +// Generated 2020-10-03 21:34:24.496436 UTC +// This header was generated with sol v3.2.1 (revision 48eea7b5) +// https://github.com/ThePhD/sol2 + +#ifndef SOL_SINGLE_INCLUDE_HPP +#define SOL_SINGLE_INCLUDE_HPP + +// beginning of sol/sol.hpp + +#ifndef SOL_HPP +#define SOL_HPP + +// beginning of sol/version.hpp + +#include "config.hpp" + +#include + +#define SOL_VERSION_MAJOR 3 +#define SOL_VERSION_MINOR 5 +#define SOL_VERSION_PATCH 0 +#define SOL_VERSION_STRING "3.5.0" +#define SOL_VERSION ((SOL_VERSION_MAJOR * 100000) + (SOL_VERSION_MINOR * 100) + (SOL_VERSION_PATCH)) + +#define SOL_IS_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) != 0) +#define SOL_IS_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3) == 0) +#define SOL_IS_DEFAULT_ON(OP_SYMBOL) ((3 OP_SYMBOL 3) > 3) +#define SOL_IS_DEFAULT_OFF(OP_SYMBOL) ((3 OP_SYMBOL 3 OP_SYMBOL 3) < 0) + +#define SOL_ON | +#define SOL_OFF ^ +#define SOL_DEFAULT_ON + +#define SOL_DEFAULT_OFF - + +#if defined(_MSC_VER) +#define SOL_COMPILER_CLANG_I_ SOL_OFF +#define SOL_COMPILER_GCC_I_ SOL_OFF +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_ON +#elif defined(__clang__) +#define SOL_COMPILER_CLANG_I_ SOL_ON +#define SOL_COMPILER_GCC_I_ SOL_OFF +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_OFF +#elif defined(__GNUC__) +#define SOL_COMPILER_CLANG_I_ SOL_OFF +#define SOL_COMPILER_GCC_I_ SOL_ON +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_OFF +#else +#define SOL_COMPILER_CLANG_I_ SOL_OFF +#define SOL_COMPILER_GCC_I_ SOL_OFF +#define SOL_COMPILER_EDG_I_ SOL_OFF +#define SOL_COMPILER_VCXX_I_ SOL_OFF +#endif + +#if defined(__MINGW32__) +#define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_ON +#else +#define SOL_COMPILER_FRONTEND_MINGW_I_ SOL_OFF +#endif + +#if SIZE_MAX <= 0xFFFFULL +#define SOL_PLATFORM_X16_I_ SOL_ON +#define SOL_PLATFORM_X86_I_ SOL_OFF +#define SOL_PLATFORM_X64_I_ SOL_OFF +#elif SIZE_MAX <= 0xFFFFFFFFULL +#define SOL_PLATFORM_X16_I_ SOL_OFF +#define SOL_PLATFORM_X86_I_ SOL_ON +#define SOL_PLATFORM_X64_I_ SOL_OFF +#else +#define SOL_PLATFORM_X16_I_ SOL_OFF +#define SOL_PLATFORM_X86_I_ SOL_OFF +#define SOL_PLATFORM_X64_I_ SOL_ON +#endif + +#define SOL_PLATFORM_ARM32_I_ SOL_OFF +#define SOL_PLATFORM_ARM64_I_ SOL_OFF + +#if defined(_WIN32) +#define SOL_PLATFORM_WINDOWS_I_ SOL_ON +#else +#define SOL_PLATFORM_WINDOWS_I_ SOL_OFF +#endif +#if defined(__APPLE__) +#define SOL_PLATFORM_APPLE_I_ SOL_ON +#else +#define SOL_PLATFORM_APPLE_I_ SOL_OFF +#endif +#if defined(__unix__) +#define SOL_PLATFORM_UNIXLIKE_I_ SOL_ON +#else +#define SOL_PLATFORM_UNIXLIKE_I_ SOL_OFF +#endif +#if defined(__linux__) +#define SOL_PLATFORM_LINUXLIKE_I_ SOL_ON +#else +#define SOL_PLATFORM_LINUXLIKE_I_ SOL_OFF +#endif + +#define SOL_PLATFORM_APPLE_IPHONE_I_ SOL_OFF +#define SOL_PLATFORM_BSDLIKE_I_ SOL_OFF + +#if defined(SOL_IN_DEBUG_DETECTED) +#if SOL_IN_DEBUG_DETECTED != 0 +#define SOL_DEBUG_BUILD_I_ SOL_ON +#else +#define SOL_DEBUG_BUILD_I_ SOL_OFF +#endif +#elif !defined(NDEBUG) +#if SOL_IS_ON(SOL_COMPILER_VCXX_I_) && defined(_DEBUG) +#define SOL_DEBUG_BUILD_I_ SOL_ON +#elif (SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_)) && !defined(__OPTIMIZE__) +#define SOL_DEBUG_BUILD_I_ SOL_ON +#else +#define SOL_DEBUG_BUILD_I_ SOL_OFF +#endif +#else +#define SOL_DEBUG_BUILD_I_ SOL_DEFAULT_OFF +#endif // We are in a debug mode of some sort + +#if defined(SOL_NO_EXCEPTIONS) +#if (SOL_NO_EXCEPTIONS != 0) +#define SOL_EXCEPTIONS_I_ SOL_OFF +#else +#define SOL_EXCEPTIONS_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) +#if !defined(_CPPUNWIND) +#define SOL_EXCEPTIONS_I_ SOL_OFF +#else +#define SOL_EXCEPTIONS_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_) +#if !defined(__EXCEPTIONS) +#define SOL_EXCEPTIONS_I_ SOL_OFF +#else +#define SOL_EXCEPTIONS_I_ SOL_ON +#endif +#else +#define SOL_EXCEPTIONS_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_RTTI) +#if (SOL_NO_RTTI != 0) +#define SOL_RTTI_I_ SOL_OFF +#else +#define SOL_RTTI_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) +#if !defined(_CPPRTTI) +#define SOL_RTTI_I_ SOL_OFF +#else +#define SOL_RTTI_I_ SOL_ON +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) || SOL_IS_ON(SOL_COMPILER_GCC_I_) +#if !defined(__GXX_RTTI) +#define SOL_RTTI_I_ SOL_OFF +#else +#define SOL_RTTI_I_ SOL_ON +#endif +#else +#define SOL_RTTI_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_NO_THREAD_LOCAL) && (SOL_NO_THREAD_LOCAL != 0) +#define SOL_USE_THREAD_LOCAL_I_ SOL_OFF +#else +#define SOL_USE_THREAD_LOCAL_I_ SOL_DEFAULT_ON +#endif // thread_local keyword is bjorked on some platforms + +#if defined(SOL_ALL_SAFETIES_ON) && (SOL_ALL_SAFETIES_ON != 0) +#define SOL_ALL_SAFETIES_ON_I_ SOL_ON +#else +#define SOL_ALL_SAFETIES_ON_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_SAFE_GETTER) && (SOL_SAFE_GETTER != 0) +#define SOL_SAFE_GETTER_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_GETTER_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_GETTER_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_GETTER_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_USERTYPE) && (SOL_SAFE_USERTYPE != 0) +#define SOL_SAFE_USERTYPE_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_USERTYPE_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_USERTYPE_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_REFERENCES) && (SOL_SAFE_REFERENCES != 0) +#define SOL_SAFE_REFERENCES_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_REFERENCES_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_REFERENCES_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if (defined(SOL_SAFE_FUNCTIONS) && (SOL_SAFE_FUNCTIONS != 0)) \ + || (defined(SOL_SAFE_FUNCTION_OBJECTS) && (SOL_SAFE_FUNCTION_OBJECTS != 0)) +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_FUNCTION_OBJECTS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_FUNCTION_CALLS) && (SOL_SAFE_FUNCTION_CALLS != 0) +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_FUNCTION_CALLS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_PROXIES) && (SOL_SAFE_PROXIES != 0) +#define SOL_SAFE_PROXIES_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_PROXIES_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_PROXIES_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_NUMERICS) && (SOL_SAFE_NUMERICS != 0) +#define SOL_SAFE_NUMERICS_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_NUMERICS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_NUMERICS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_SAFE_STACK_CHECK) && (SOL_SAFE_STACK_CHECK != 0) +#define SOL_SAFE_STACK_CHECK_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_SAFE_STACK_CHECK_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_ON +#else +#define SOL_SAFE_STACK_CHECK_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if (defined(SOL_NO_CHECK_NUMBER_PRECISION) && (SOL_NO_CHECK_NUMBER_PRECISION != 0)) \ + || (defined(SOL_NO_CHECKING_NUMBER_PRECISION) && (SOL_NO_CHECKING_NUMBER_PRECISION != 0)) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_OFF +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON +#elif SOL_IS_ON(SOL_SAFE_NUMERICS_I_) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_ON +#else +#define SOL_NUMBER_PRECISION_CHECKS_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_STRINGS_ARE_NUMBERS) +#if (SOL_STRINGS_ARE_NUMBERS != 0) +#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_ON +#else +#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_OFF +#endif +#else +#define SOL_STRINGS_ARE_NUMBERS_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_ENABLE_INTEROP) && (SOL_ENABLE_INTEROP != 0) \ + || defined(SOL_USE_INTEROP) && (SOL_USE_INTEROP != 0) +#define SOL_USE_INTEROP_I_ SOL_ON +#else +#define SOL_USE_INTEROP_I_ SOL_DEFAULT_OFF +#endif + +#if defined(SOL_NO_NIL) +#if (SOL_NO_NIL != 0) +#define SOL_NIL_I_ SOL_OFF +#else +#define SOL_NIL_I_ SOL_ON +#endif +#elif defined(__MAC_OS_X_VERSION_MAX_ALLOWED) || defined(__OBJC__) || defined(nil) +#define SOL_NIL_I_ SOL_DEFAULT_OFF +#else +#define SOL_NIL_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USERTYPE_TYPE_BINDING_INFO) +#if (SOL_USERTYPE_TYPE_BINDING_INFO != 0) +#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_ON +#else +#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_OFF +#endif +#else +#define SOL_USERTYPE_TYPE_BINDING_INFO_I_ SOL_DEFAULT_ON +#endif // We should generate a my_type.__type table with lots of class information for usertypes + +#if defined(SOL_AUTOMAGICAL_TYPES_BY_DEFAULT) +#if (SOL_AUTOMAGICAL_TYPES_BY_DEFAULT != 0) +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON +#else +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF +#endif +#elif defined(SOL_DEFAULT_AUTOMAGICAL_USERTYPES) +#if (SOL_DEFAULT_AUTOMAGICAL_USERTYPES != 0) +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_ON +#else +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_OFF +#endif +#else +#define SOL_DEFAULT_AUTOMAGICAL_USERTYPES_I_ SOL_DEFAULT_ON +#endif // make is_automagical on/off by default + +#if defined(SOL_STD_VARIANT) +#if (SOL_STD_VARIANT != 0) +#define SOL_STD_VARIANT_I_ SOL_ON +#else +#define SOL_STD_VARIANT_I_ SOL_OFF +#endif +#else +#if SOL_IS_ON(SOL_COMPILER_CLANG_I_) && SOL_IS_ON(SOL_PLATFORM_APPLE_I_) +#if defined(__has_include) +#if __has_include() +#define SOL_STD_VARIANT_I_ SOL_ON +#else +#define SOL_STD_VARIANT_I_ SOL_OFF +#endif +#else +#define SOL_STD_VARIANT_I_ SOL_OFF +#endif +#else +#define SOL_STD_VARIANT_I_ SOL_DEFAULT_ON +#endif +#endif // make is_automagical on/off by default + +#if defined(SOL_NOEXCEPT_FUNCTION_TYPE) +#if (SOL_NOEXCEPT_FUNCTION_TYPE != 0) +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON +#else +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF +#endif +#else +#if defined(__cpp_noexcept_function_type) +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_ON +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) && (defined(_MSVC_LANG) && (_MSVC_LANG < 201403L)) + // There is a bug in the VC++ compiler?? + // on /std:c++latest under x86 conditions (VS 15.5.2), + // compiler errors are tossed for noexcept markings being on function types + // that are identical in every other way to their non-noexcept marked types function types... + // VS 2019: There is absolutely a bug. +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_OFF +#else +#define SOL_USE_NOEXCEPT_FUNCTION_TYPE_I_ SOL_DEFAULT_ON +#endif +#endif // noexcept is part of a function's type + +#if defined(SOL_STACK_STRING_OPTIMIZATION_SIZE) && SOL_STACK_STRING_OPTIMIZATION_SIZE > 0 +#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ SOL_STACK_STRING_OPTIMIZATION_SIZE +#else +#define SOL_OPTIMIZATION_STRING_CONVERSION_STACK_SIZE_I_ 1024 +#endif + +#if defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 +#define SOL_ID_SIZE_I_ SOL_ID_SIZE +#else +#define SOL_ID_SIZE_I_ 512 +#endif + +#if defined(LUA_IDSIZE) && LUA_IDSIZE > 0 +#define SOL_FILE_ID_SIZE_I_ LUA_IDSIZE +#elif defined(SOL_ID_SIZE) && SOL_ID_SIZE > 0 +#define SOL_FILE_ID_SIZE_I_ SOL_FILE_ID_SIZE +#else +#define SOL_FILE_ID_SIZE_I_ 2048 +#endif + +#if defined(SOL_PRINT_ERRORS) +#if (SOL_PRINT_ERRORS != 0) +#define SOL_PRINT_ERRORS_I_ SOL_ON +#else +#define SOL_PRINT_ERRORS_I_ SOL_OFF +#endif +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_PRINT_ERRORS_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_PRINT_ERRORS_I_ SOL_DEFAULT_ON +#else +#define SOL_PRINT_ERRORS_I_ SOL_OFF +#endif +#endif + +#if defined(SOL_DEFAULT_PASS_ON_ERROR) && (SOL_DEFAULT_PASS_ON_ERROR != 0) +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON +#else +#if SOL_IS_ON(SOL_ALL_SAFETIES_ON_I_) +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_ON +#elif SOL_IS_ON(SOL_DEBUG_BUILD_I_) +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_DEFAULT_ON +#else +#define SOL_DEFAULT_PASS_ON_ERROR_I_ SOL_OFF +#endif +#endif + +#if defined(SOL_USING_CXX_LUA) +#if (SOL_USING_CXX_LUA != 0) +#define SOL_USE_CXX_LUA_I_ SOL_ON +#else +#define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif +#elif defined(SOL_USE_CXX_LUA) +#if (SOL_USE_CXX_LUA != 0) +#define SOL_USE_CXX_LUA_I_ SOL_ON +#else +#define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif +#else +#define SOL_USE_CXX_LUA_I_ SOL_OFF +#endif + +#if defined(SOL_USING_CXX_LUAJIT) +#if (SOL_USING_CXX_LUA != 0) +#define SOL_USE_CXX_LUAJIT_I_ SOL_ON +#else +#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif +#elif defined(SOL_USE_CXX_LUAJIT) +#if (SOL_USE_CXX_LUA != 0) +#define SOL_USE_CXX_LUAJIT_I_ SOL_ON +#else +#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif +#else +#define SOL_USE_CXX_LUAJIT_I_ SOL_OFF +#endif + +#if defined(SOL_NO_LUA_HPP) +#if (SOL_NO_LUA_HPP != 0) +#define SOL_USE_LUA_HPP_I_ SOL_OFF +#else +#define SOL_USE_LUA_HPP_I_ SOL_ON +#endif +#elif defined(SOL_USING_CXX_LUA) +#define SOL_USE_LUA_HPP_I_ SOL_OFF +#elif defined(__has_include) +#if __has_include() +#define SOL_USE_LUA_HPP_I_ SOL_ON +#else +#define SOL_USE_LUA_HPP_I_ SOL_OFF +#endif +#else +#define SOL_USE_LUA_HPP_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_CONTAINERS_START) +#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START +#elif defined(SOL_CONTAINERS_START_INDEX) +#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINERS_START_INDEX +#elif defined(SOL_CONTAINER_START_INDEX) +#define SOL_CONTAINER_START_INDEX_I_ SOL_CONTAINER_START_INDEX +#else +#define SOL_CONTAINER_START_INDEX_I_ 1 +#endif + +#if defined (SOL_NO_MEMORY_ALIGNMENT) +#if (SOL_NO_MEMORY_ALIGNMENT != 0) +#define SOL_ALIGN_MEMORY_I_ SOL_OFF +#else +#define SOL_ALIGN_MEMORY_I_ SOL_ON +#endif +#else +#define SOL_ALIGN_MEMORY_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_USE_BOOST) +#if (SOL_USE_BOOST != 0) +#define SOL_USE_BOOST_I_ SOL_ON +#else +#define SOL_USE_BOOST_I_ SOL_OFF +#endif +#else +#define SOL_USE_BOOST_I_ SOL_OFF +#endif + +#if defined(SOL_USE_UNSAFE_BASE_LOOKUP) +#if (SOL_USE_UNSAFE_BASE_LOOKUP != 0) +#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_ON +#else +#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF +#endif +#else +#define SOL_USE_UNSAFE_BASE_LOOKUP_I_ SOL_OFF +#endif + +#if defined(SOL_INSIDE_UNREAL) +#if (SOL_INSIDE_UNREAL != 0) +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON +#else +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_OFF +#endif +#else +#if defined(UE_BUILD_DEBUG) || defined(UE_BUILD_DEVELOPMENT) || defined(UE_BUILD_TEST) || defined(UE_BUILD_SHIPPING) || defined(UE_SERVER) +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_ON +#else +#define SOL_INSIDE_UNREAL_ENGINE_I_ SOL_DEFAULT_OFF +#endif +#endif + +#if defined(SOL_NO_COMPAT) +#if (SOL_NO_COMPAT != 0) +#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_OFF +#else +#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_ON +#endif +#else +#define SOL_USE_COMPATIBILITY_LAYER_I_ SOL_DEFAULT_ON +#endif + +#if defined(SOL_GET_FUNCTION_POINTER_UNSAFE) +#if (SOL_GET_FUNCTION_POINTER_UNSAFE != 0) +#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_ON +#else +#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_OFF +#endif +#else +#define SOL_GET_FUNCTION_POINTER_UNSAFE_I_ SOL_DEFAULT_OFF +#endif + +#if SOL_IS_ON(SOL_COMPILER_FRONTEND_MINGW_I_) && defined(__GNUC__) && (__GNUC__ < 6) + // MinGW is off its rocker in some places... +#define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_ON +#else +#define SOL_MINGW_CCTYPE_IS_POISONED_I_ SOL_DEFAULT_OFF +#endif + +// end of sol/version.hpp + +#if SOL_IS_ON(SOL_INSIDE_UNREAL_ENGINE_I_) +#ifdef check +#pragma push_macro("check") +#undef check +#endif +#endif // Unreal Engine 4 Bullshit + +#if SOL_IS_ON(SOL_COMPILER_GCC_I_) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wshadow" +#pragma GCC diagnostic ignored "-Wconversion" +#if __GNUC__ > 6 +#pragma GCC diagnostic ignored "-Wnoexcept-type" +#endif +#elif SOL_IS_ON(SOL_COMPILER_CLANG_I_) +#elif SOL_IS_ON(SOL_COMPILER_VCXX_I_) +#pragma warning(push) +#pragma warning(disable : 4505) // unreferenced local function has been removed GEE THANKS +#endif // clang++ vs. g++ vs. VC++ + +// beginning of sol/forward.hpp + +#ifndef SOL_FORWARD_HPP +#define SOL_FORWARD_HPP + +#include +#include +#include +#include +#include + +#if SOL_IS_ON(SOL_USE_CXX_LUA_I_) || SOL_IS_ON(SOL_USE_CXX_LUAJIT_I_) +struct lua_State; +#else +extern "C" { + struct lua_State; +} +#endif // C++ Mangling for Lua vs. Not + +namespace sol { + + enum class type; + + class stateless_reference; + template + class basic_reference; + using reference = basic_reference; + using main_reference = basic_reference; + class stateless_stack_reference; + class stack_reference; + + template + class basic_bytecode; + + struct lua_value; + + struct proxy_base_tag; + template + struct proxy_base; + template + struct table_proxy; + + template + class basic_table_core; + template + using table_core = basic_table_core; + template + using main_table_core = basic_table_core; + template + using stack_table_core = basic_table_core; + template + using basic_table = basic_table_core; + using table = table_core; + using global_table = table_core; + using main_table = main_table_core; + using main_global_table = main_table_core; + using stack_table = stack_table_core; + using stack_global_table = stack_table_core; + + template + struct basic_lua_table; + using lua_table = basic_lua_table; + using stack_lua_table = basic_lua_table; + + template + class basic_usertype; + template + using usertype = basic_usertype; + template + using stack_usertype = basic_usertype; + + template + class basic_metatable; + using metatable = basic_metatable; + using stack_metatable = basic_metatable; + + template + struct basic_environment; + using environment = basic_environment; + using main_environment = basic_environment; + using stack_environment = basic_environment; + + template + class basic_function; + template + class basic_protected_function; + using unsafe_function = basic_function; + using safe_function = basic_protected_function; + using main_unsafe_function = basic_function; + using main_safe_function = basic_protected_function; + using stack_unsafe_function = basic_function; + using stack_safe_function = basic_protected_function; + using stack_aligned_unsafe_function = basic_function; + using stack_aligned_safe_function = basic_protected_function; + using protected_function = safe_function; + using main_protected_function = main_safe_function; + using stack_protected_function = stack_safe_function; + using stack_aligned_protected_function = stack_aligned_safe_function; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) + using function = protected_function; + using main_function = main_protected_function; + using stack_function = stack_protected_function; + using stack_aligned_function = stack_aligned_safe_function; +#else + using function = unsafe_function; + using main_function = main_unsafe_function; + using stack_function = stack_unsafe_function; + using stack_aligned_function = stack_aligned_unsafe_function; +#endif + using stack_aligned_stack_handler_function = basic_protected_function; + + struct unsafe_function_result; + struct protected_function_result; + using safe_function_result = protected_function_result; +#if SOL_IS_ON(SOL_SAFE_FUNCTION_OBJECTS_I_) + using function_result = safe_function_result; +#else + using function_result = unsafe_function_result; +#endif + + template + class basic_object_base; + template + class basic_object; + template + class basic_userdata; + template + class basic_lightuserdata; + template + class basic_coroutine; + template + class basic_thread; + + using object = basic_object; + using userdata = basic_userdata; + using lightuserdata = basic_lightuserdata; + using thread = basic_thread; + using coroutine = basic_coroutine; + using main_object = basic_object; + using main_userdata = basic_userdata; + using main_lightuserdata = basic_lightuserdata; + using main_coroutine = basic_coroutine; + using stack_object = basic_object; + using stack_userdata = basic_userdata; + using stack_lightuserdata = basic_lightuserdata; + using stack_thread = basic_thread; + using stack_coroutine = basic_coroutine; + + struct stack_proxy_base; + struct stack_proxy; + struct variadic_args; + struct variadic_results; + struct stack_count; + struct this_state; + struct this_main_state; + struct this_environment; + + class state_view; + class state; + + template + struct as_table_t; + template + struct as_container_t; + template + struct nested; + template + struct light; + template + struct user; + template + struct as_args_t; + template + struct protect_t; + template + struct policy_wrapper; + + template + struct usertype_traits; + template + struct unique_usertype_traits; + + template + struct types { + typedef std::make_index_sequence indices; + static constexpr std::size_t size() { + return sizeof...(Args); + } + }; + + template + struct derive : std::false_type { + typedef types<> type; + }; + + template + struct base : std::false_type { + typedef types<> type; + }; + + template + struct weak_derive { + static bool value; + }; + + template + bool weak_derive::value = false; + + namespace stack { + struct record; + } + +#if SOL_IS_OFF(SOL_USE_BOOST_I_) + template + class optional; + + template + class optional; +#endif + + using check_handler_type = int(lua_State*, int, type, type, const char*); + +} // namespace sol + +#define SOL_BASE_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct base : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() +#define SOL_DERIVED_CLASSES(T, ...) \ + namespace sol { \ + template <> \ + struct derive : std::true_type { \ + typedef ::sol::types<__VA_ARGS__> type; \ + }; \ + } \ + void a_sol3_detail_function_decl_please_no_collide() + +#endif // SOL_FORWARD_HPP +// end of sol/forward.hpp + +// beginning of sol/forward_detail.hpp + +#ifndef SOL_FORWARD_DETAIL_HPP +#define SOL_FORWARD_DETAIL_HPP + +// beginning of sol/traits.hpp + +// beginning of sol/tuple.hpp + +// beginning of sol/base_traits.hpp + +#include + +namespace sol { + namespace detail { + struct unchecked_t {}; + const unchecked_t unchecked = unchecked_t{}; + } // namespace detail + + namespace meta { + using sfinae_yes_t = std::true_type; + using sfinae_no_t = std::false_type; + + template + using void_t = void; + + template + using unqualified = std::remove_cv>; + + template + using unqualified_t = typename unqualified::type; + + namespace meta_detail { + template + struct unqualified_non_alias : unqualified {}; + + template