From 3ba0bdf7084f3d8eb37c64f0872d4ed912edede8 Mon Sep 17 00:00:00 2001 From: NotDSF <67711164+NotDSF@users.noreply.github.com> Date: Tue, 9 Nov 2021 22:54:53 +0000 Subject: [PATCH] Save bytecode to file through CLI (#170) Using --compile=binary it's now possible to produce binary bytecode so that it can be compiled offline and loaded into the VM. --- CLI/Repl.cpp | 46 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 39 insertions(+), 7 deletions(-) diff --git a/CLI/Repl.cpp b/CLI/Repl.cpp index 323ab144..a5bd5737 100644 --- a/CLI/Repl.cpp +++ b/CLI/Repl.cpp @@ -13,6 +13,17 @@ #include +#ifdef _WIN32 + #include + #include +#endif + +enum class CompileFormat +{ + Default, + Binary +}; + static int lua_loadstring(lua_State* L) { size_t l = 0; @@ -370,7 +381,7 @@ static void reportError(const char* name, const Luau::CompileError& error) report(name, error.getLocation(), "CompileError", error.what()); } -static bool compileFile(const char* name) +static bool compileFile(const char* name, CompileFormat format) { std::optional source = readFile(name); if (!source) @@ -387,7 +398,20 @@ static bool compileFile(const char* name) Luau::compileOrThrow(bcb, *source); - printf("%s", bcb.dumpEverything().c_str()); + switch (format) + { + case CompileFormat::Default: + printf("%s", bcb.dumpEverything().c_str()); + break; + case CompileFormat::Binary: + #ifdef _WIN32 + _setmode(_fileno(stdout), _O_BINARY); + #endif + + std::string Bytecode = bcb.getBytecode(); + fwrite(Bytecode.c_str(), 1, Bytecode.size(), stdout); + break; + } return true; } @@ -412,7 +436,7 @@ static void displayHelp(const char* argv0) printf("\n"); printf("Available modes:\n"); printf(" omitted: compile and run input files one by one\n"); - printf(" --compile: compile input files and output resulting bytecode\n"); + printf(" --compile[=format]: compile input files and output resulting formatted bytecode (binary or text)\n"); printf("\n"); printf("Available options:\n"); printf(" --profile[=N]: profile the code using N Hz sampling (default 10000) and output results to profile.out\n"); @@ -444,8 +468,16 @@ int main(int argc, char** argv) return 0; } - if (argc >= 2 && strcmp(argv[1], "--compile") == 0) - { + + if (argc >= 2 && strncmp(argv[1], "--compile", strlen("--compile")) == 0) + { + CompileFormat format = CompileFormat::Default; + + if (strcmp(argv[1], "--compile=binary") == 0) + { + format = CompileFormat::Binary; + } + int failed = 0; for (int i = 2; i < argc; ++i) @@ -457,12 +489,12 @@ int main(int argc, char** argv) { traverseDirectory(argv[i], [&](const std::string& name) { if (name.length() > 4 && name.rfind(".lua") == name.length() - 4) - failed += !compileFile(name.c_str()); + failed += !compileFile(name.c_str(), format); }); } else { - failed += !compileFile(argv[i]); + failed += !compileFile(argv[i], format); } }