mirror of
https://github.com/luau-lang/luau.git
synced 2024-11-16 06:45:44 +08:00
d50b079325
- Rework transaction log used for type checking which should result in more robust type checking internals with fewer bugs - Reduce the amount of memory consumed by type checker on large module graphs - Type checker now errors on attempts to change the type of imported module fields - The return type of newproxy is now any (fixes #296) - Implement new number printing algorithm (Schubfach) which makes tostring() produce precise (round-trippable) and short decimal output up to 10x faster - Fix lua_Debug::linedefined to point to the line with the function definition instead of the first statement (fixes #265) - Fix minor bugs in Tab completion in Repl - Repl now saves/restores command history in ~/.luau_history
115 lines
2.6 KiB
C++
115 lines
2.6 KiB
C++
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
|
#include "lua.h"
|
|
#include "lualib.h"
|
|
#include "luacode.h"
|
|
|
|
#include "Luau/Common.h"
|
|
|
|
#include <string>
|
|
|
|
#include <string.h>
|
|
|
|
static void setupState(lua_State* L)
|
|
{
|
|
luaL_openlibs(L);
|
|
|
|
luaL_sandbox(L);
|
|
}
|
|
|
|
static std::string runCode(lua_State* L, const std::string& source)
|
|
{
|
|
size_t bytecodeSize = 0;
|
|
char* bytecode = luau_compile(source.data(), source.length(), nullptr, &bytecodeSize);
|
|
int result = luau_load(L, "=stdin", bytecode, bytecodeSize, 0);
|
|
free(bytecode);
|
|
|
|
if (result != 0)
|
|
{
|
|
size_t len;
|
|
const char* msg = lua_tolstring(L, -1, &len);
|
|
|
|
std::string error(msg, len);
|
|
lua_pop(L, 1);
|
|
|
|
return error;
|
|
}
|
|
|
|
lua_State* T = lua_newthread(L);
|
|
|
|
lua_pushvalue(L, -2);
|
|
lua_remove(L, -3);
|
|
lua_xmove(L, T, 1);
|
|
|
|
int status = lua_resume(T, NULL, 0);
|
|
|
|
if (status == 0)
|
|
{
|
|
int n = lua_gettop(T);
|
|
|
|
if (n)
|
|
{
|
|
luaL_checkstack(T, LUA_MINSTACK, "too many results to print");
|
|
lua_getglobal(T, "print");
|
|
lua_insert(T, 1);
|
|
lua_pcall(T, n, 0, 0);
|
|
}
|
|
|
|
lua_pop(L, 1); // pop T
|
|
return std::string();
|
|
}
|
|
else
|
|
{
|
|
std::string error;
|
|
|
|
lua_Debug ar;
|
|
if (lua_getinfo(L, 0, "sln", &ar))
|
|
{
|
|
error += ar.short_src;
|
|
error += ':';
|
|
error += std::to_string(ar.currentline);
|
|
error += ": ";
|
|
}
|
|
|
|
if (status == LUA_YIELD)
|
|
{
|
|
error += "thread yielded unexpectedly";
|
|
}
|
|
else if (const char* str = lua_tostring(T, -1))
|
|
{
|
|
error += str;
|
|
}
|
|
|
|
error += "\nstack backtrace:\n";
|
|
error += lua_debugtrace(T);
|
|
|
|
lua_pop(L, 1); // pop T
|
|
return error;
|
|
}
|
|
}
|
|
|
|
extern "C" const char* executeScript(const char* source)
|
|
{
|
|
// setup flags
|
|
for (Luau::FValue<bool>* flag = Luau::FValue<bool>::list; flag; flag = flag->next)
|
|
if (strncmp(flag->name, "Luau", 4) == 0)
|
|
flag->value = true;
|
|
|
|
// create new state
|
|
std::unique_ptr<lua_State, void (*)(lua_State*)> globalState(luaL_newstate(), lua_close);
|
|
lua_State* L = globalState.get();
|
|
|
|
// setup state
|
|
setupState(L);
|
|
|
|
// sandbox thread
|
|
luaL_sandboxthread(L);
|
|
|
|
// static string for caching result (prevents dangling ptr on function exit)
|
|
static std::string result;
|
|
|
|
// run code + collect error
|
|
result = runCode(L, source);
|
|
|
|
return result.empty() ? NULL : result.c_str();
|
|
}
|