replaced luajit with luau
This commit is contained in:
parent
f4407830fe
commit
16eeb9b276
74 changed files with 7603 additions and 1134 deletions
|
@ -1,28 +1,30 @@
|
|||
function mulquat(a, b)
|
||||
return {
|
||||
mulquat = function(a, b)
|
||||
return {
|
||||
a[4] * b[1] + b[4] * a[1] + a[2] * b[3] - b[2] * a[3],
|
||||
a[4] * b[2] + b[4] * a[2] + a[3] * b[1] - b[3] * a[1],
|
||||
a[4] * b[3] + b[4] * a[3] + a[1] * b[2] - b[1] * a[2],
|
||||
a[4] * b[4] - a[1] * b[1] - a[2] * b[2] - a[3] * b[3]
|
||||
}
|
||||
end
|
||||
end,
|
||||
|
||||
function makeQuatFromYaw(yaw)
|
||||
makeQuatFromYaw = function(yaw)
|
||||
local syaw = math.sin(yaw * 0.5)
|
||||
local cyaw = math.cos(yaw * 0.5)
|
||||
return {0, syaw, 0, cyaw }
|
||||
end
|
||||
end,
|
||||
|
||||
function makeQuatFromPitch(pitch)
|
||||
makeQuatFromPitch = function(pitch)
|
||||
local spitch = math.sin(pitch * 0.5)
|
||||
local cpitch = math.cos(pitch * 0.5)
|
||||
return {-spitch, 0, 0, cpitch}
|
||||
end
|
||||
end,
|
||||
|
||||
function yawToDir(yaw)
|
||||
yawToDir = function(yaw)
|
||||
return {math.sin(yaw), 0, math.cos(yaw)}
|
||||
end
|
||||
end,
|
||||
|
||||
function mulVec3Num(v, f)
|
||||
mulVec3Num = function(v, f)
|
||||
return {v[1] * f, v[2] * f, v[3] * f}
|
||||
end
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
require "scripts/math"
|
||||
local math = require "scripts/math"
|
||||
|
||||
local forward = 0
|
||||
local backward = 0
|
||||
|
@ -77,7 +77,7 @@ end
|
|||
|
||||
function onControllerHit(obj)
|
||||
local a = obj.rigid_actor
|
||||
local force = mulVec3Num(yawToDir(yaw), 50)
|
||||
local force = math.mulVec3Num(math.yawToDir(yaw), 50)
|
||||
a:applyForce(force)
|
||||
end
|
||||
|
||||
|
@ -127,8 +127,8 @@ function update(td)
|
|||
this.animator:setBoolInput(crouched_input_idx, crouched)
|
||||
this.animator:setBoolInput(falling_input_idx, gravity_speed < -4)
|
||||
this.animator:setBoolInput(aiming_input_idx, aiming)
|
||||
local yaw_rot = makeQuatFromYaw(yaw)
|
||||
local pitch_rot = makeQuatFromPitch(pitch)
|
||||
local yaw_rot = math.makeQuatFromYaw(yaw)
|
||||
local pitch_rot = math.makeQuatFromPitch(pitch)
|
||||
this.rotation = yaw_rot
|
||||
camera_pivot.rotation = mulquat(yaw_rot, pitch_rot)
|
||||
camera_pivot.rotation = math.mulquat(yaw_rot, pitch_rot)
|
||||
end
|
||||
|
|
56
external/luajit/COPYRIGHT
vendored
56
external/luajit/COPYRIGHT
vendored
|
@ -1,56 +0,0 @@
|
|||
===============================================================================
|
||||
LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
|
||||
|
||||
Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
|
||||
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.
|
||||
|
||||
[ MIT license: http://www.opensource.org/licenses/mit-license.php ]
|
||||
|
||||
===============================================================================
|
||||
[ LuaJIT includes code from Lua 5.1/5.2, which has this license statement: ]
|
||||
|
||||
Copyright (C) 1994-2012 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.
|
||||
|
||||
===============================================================================
|
||||
[ LuaJIT includes code from dlmalloc, which has this license statement: ]
|
||||
|
||||
This is a version (aka dlmalloc) of malloc/free/realloc written by
|
||||
Doug Lea and released to the public domain, as explained at
|
||||
http://creativecommons.org/licenses/publicdomain
|
||||
|
||||
===============================================================================
|
162
external/luajit/include/lauxlib.h
vendored
162
external/luajit/include/lauxlib.h
vendored
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
** $Id: lauxlib.h,v 1.88.1.1 2007/12/27 13:02:25 roberto Exp $
|
||||
** Auxiliary functions for building Lua libraries
|
||||
** See Copyright Notice in lua.h
|
||||
*/
|
||||
|
||||
|
||||
#ifndef lauxlib_h
|
||||
#define lauxlib_h
|
||||
|
||||
|
||||
//#include <stddef.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
|
||||
/* extra error code for `luaL_load' */
|
||||
#define LUA_ERRFILE (LUA_ERRERR+1)
|
||||
|
||||
typedef struct luaL_Reg {
|
||||
const char *name;
|
||||
lua_CFunction func;
|
||||
} luaL_Reg;
|
||||
|
||||
LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname,
|
||||
const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_register) (lua_State *L, const char *libname,
|
||||
const luaL_Reg *l);
|
||||
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 int (luaL_typerror) (lua_State *L, int narg, const char *tname);
|
||||
LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);
|
||||
LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,
|
||||
size_t *l);
|
||||
LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,
|
||||
const char *def, size_t *l);
|
||||
LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);
|
||||
|
||||
LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);
|
||||
LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,
|
||||
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 narg, int t);
|
||||
LUALIB_API void (luaL_checkany) (lua_State *L, int narg);
|
||||
|
||||
LUALIB_API int (luaL_newmetatable) (lua_State *L, 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 narg, const char *def,
|
||||
const char *const lst[]);
|
||||
|
||||
/* pre-defined 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_loadfile) (lua_State *L, const char *filename);
|
||||
LUALIB_API int (luaL_loadbuffer) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name);
|
||||
LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
|
||||
|
||||
LUALIB_API lua_State *(luaL_newstate) (void);
|
||||
|
||||
|
||||
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
|
||||
const char *r);
|
||||
|
||||
LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx,
|
||||
const char *fname, int szhint);
|
||||
|
||||
/* From Lua 5.2. */
|
||||
LUALIB_API int luaL_fileresult(lua_State *L, int stat, const char *fname);
|
||||
LUALIB_API int luaL_execresult(lua_State *L, int stat);
|
||||
LUALIB_API int (luaL_loadfilex) (lua_State *L, const char *filename,
|
||||
const char *mode);
|
||||
LUALIB_API int (luaL_loadbufferx) (lua_State *L, const char *buff, size_t sz,
|
||||
const char *name, const char *mode);
|
||||
LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, const char *msg,
|
||||
int level);
|
||||
LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup);
|
||||
LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname,
|
||||
int sizehint);
|
||||
LUALIB_API void *(luaL_testudata) (lua_State *L, int ud, const char *tname);
|
||||
LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define luaL_argcheck(L, cond,numarg,extramsg) \
|
||||
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
|
||||
#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
|
||||
#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
|
||||
#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)))
|
||||
|
||||
#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)))
|
||||
|
||||
/* From Lua 5.2. */
|
||||
#define luaL_newlibtable(L, l) \
|
||||
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
|
||||
#define luaL_newlib(L, l) (luaL_newlibtable(L, l), luaL_setfuncs(L, l, 0))
|
||||
|
||||
/*
|
||||
** {======================================================
|
||||
** Generic Buffer manipulation
|
||||
** =======================================================
|
||||
*/
|
||||
|
||||
|
||||
#if 0
|
||||
typedef struct luaL_Buffer {
|
||||
char *p; /* current position in buffer */
|
||||
int lvl; /* number of strings in the stack (level) */
|
||||
lua_State *L;
|
||||
char buffer[LUAL_BUFFERSIZE];
|
||||
} luaL_Buffer;
|
||||
|
||||
#define luaL_addchar(B,c) \
|
||||
((void)((B)->p < ((B)->buffer+LUAL_BUFFERSIZE) || luaL_prepbuffer(B)), \
|
||||
(*(B)->p++ = (char)(c)))
|
||||
|
||||
/* compatibility only */
|
||||
#define luaL_putchar(B,c) luaL_addchar(B,c)
|
||||
|
||||
#define luaL_addsize(B,n) ((B)->p += (n))
|
||||
|
||||
LUALIB_API void (luaL_buffinit) (lua_State *L, luaL_Buffer *B);
|
||||
LUALIB_API char *(luaL_prepbuffer) (luaL_Buffer *B);
|
||||
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);
|
||||
#endif
|
||||
|
||||
|
||||
/* }====================================================== */
|
||||
|
||||
#endif
|
401
external/luajit/include/lua.h
vendored
401
external/luajit/include/lua.h
vendored
|
@ -1,401 +0,0 @@
|
|||
/*
|
||||
** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
|
||||
** Lua - An Extensible Extension 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 <stdarg.h>
|
||||
//#include <stddef.h>
|
||||
|
||||
|
||||
#include "luaconf.h"
|
||||
|
||||
|
||||
#define LUA_VERSION "Lua 5.1"
|
||||
#define LUA_RELEASE "Lua 5.1.4"
|
||||
#define LUA_VERSION_NUM 501
|
||||
#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
|
||||
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
|
||||
|
||||
|
||||
/* mark for precompiled code (`<esc>Lua') */
|
||||
#define LUA_SIGNATURE "\033Lua"
|
||||
|
||||
/* option for multiple returns in `lua_pcall' and `lua_call' */
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
|
||||
/*
|
||||
** pseudo-indices
|
||||
*/
|
||||
#define LUA_REGISTRYINDEX (-10000)
|
||||
#define LUA_ENVIRONINDEX (-10001)
|
||||
#define LUA_GLOBALSINDEX (-10002)
|
||||
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(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;
|
||||
|
||||
typedef int (*lua_CFunction) (lua_State *L);
|
||||
|
||||
|
||||
/*
|
||||
** 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);
|
||||
|
||||
|
||||
/*
|
||||
** prototype for memory-allocation functions
|
||||
*/
|
||||
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
|
||||
|
||||
|
||||
/*
|
||||
** 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
|
||||
|
||||
|
||||
|
||||
/* minimum Lua stack available to a C function */
|
||||
#define LUA_MINSTACK 20
|
||||
|
||||
|
||||
/*
|
||||
** generic extra include file
|
||||
*/
|
||||
#if defined(LUA_USER_H)
|
||||
#include LUA_USER_H
|
||||
#endif
|
||||
|
||||
|
||||
/* type of numbers in Lua */
|
||||
typedef LUA_NUMBER lua_Number;
|
||||
|
||||
|
||||
/* type for integer functions */
|
||||
typedef LUA_INTEGER lua_Integer;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** 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 lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
|
||||
|
||||
|
||||
/*
|
||||
** basic stack manipulation
|
||||
*/
|
||||
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_remove) (lua_State *L, int idx);
|
||||
LUA_API void (lua_insert) (lua_State *L, int idx);
|
||||
LUA_API void (lua_replace) (lua_State *L, int idx);
|
||||
LUA_API int (lua_checkstack) (lua_State *L, int sz);
|
||||
|
||||
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_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 int (lua_equal) (lua_State *L, int idx1, int idx2);
|
||||
LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
|
||||
LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
|
||||
|
||||
LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
|
||||
LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
|
||||
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 size_t (lua_objlen) (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);
|
||||
|
||||
|
||||
/*
|
||||
** 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 void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
|
||||
LUA_API void (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 void (lua_gettable) (lua_State *L, int idx);
|
||||
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
|
||||
LUA_API void (lua_rawget) (lua_State *L, int idx);
|
||||
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
|
||||
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
|
||||
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
|
||||
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
|
||||
LUA_API void (lua_getfenv) (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
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_rawset) (lua_State *L, int idx);
|
||||
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
|
||||
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
|
||||
LUA_API int (lua_setfenv) (lua_State *L, int idx);
|
||||
|
||||
|
||||
/*
|
||||
** `load' and `call' functions (load and run Lua code)
|
||||
*/
|
||||
LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
|
||||
LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
|
||||
LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
|
||||
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
|
||||
const char *chunkname);
|
||||
|
||||
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
|
||||
|
||||
|
||||
/*
|
||||
** coroutine functions
|
||||
*/
|
||||
LUA_API int (lua_yield) (lua_State *L, int nresults);
|
||||
LUA_API int (lua_resume) (lua_State *L, int narg);
|
||||
LUA_API int (lua_status) (lua_State *L);
|
||||
|
||||
/*
|
||||
** 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
|
||||
|
||||
LUA_API int (lua_gc) (lua_State *L, int what, int data);
|
||||
|
||||
|
||||
/*
|
||||
** 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 lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
|
||||
LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#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_strlen(L,i) lua_objlen(L, (i))
|
||||
|
||||
#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_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
|
||||
|
||||
#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
|
||||
#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
|
||||
|
||||
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** compatibility macros and functions
|
||||
*/
|
||||
|
||||
#define lua_open() luaL_newstate()
|
||||
|
||||
#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
|
||||
|
||||
#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
|
||||
|
||||
#define lua_Chunkreader lua_Reader
|
||||
#define lua_Chunkwriter lua_Writer
|
||||
|
||||
|
||||
/* hack */
|
||||
LUA_API void lua_setlevel (lua_State *from, lua_State *to);
|
||||
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Debug API
|
||||
** =======================================================================
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
** Event codes
|
||||
*/
|
||||
#define LUA_HOOKCALL 0
|
||||
#define LUA_HOOKRET 1
|
||||
#define LUA_HOOKLINE 2
|
||||
#define LUA_HOOKCOUNT 3
|
||||
#define LUA_HOOKTAILRET 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 debuger 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 int 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);
|
||||
|
||||
/* From Lua 5.2. */
|
||||
LUA_API void *lua_upvalueid (lua_State *L, int idx, int n);
|
||||
LUA_API void lua_upvaluejoin (lua_State *L, int idx1, int n1, int idx2, int n2);
|
||||
LUA_API int lua_loadx (lua_State *L, lua_Reader reader, void *dt,
|
||||
const char *chunkname, const char *mode);
|
||||
LUA_API const lua_Number *lua_version (lua_State *L);
|
||||
LUA_API void lua_copy (lua_State *L, int fromidx, int toidx);
|
||||
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);
|
||||
|
||||
/* From Lua 5.3. */
|
||||
LUA_API int lua_isyieldable (lua_State *L);
|
||||
|
||||
|
||||
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) */
|
||||
int currentline; /* (l) */
|
||||
int nups; /* (u) number of upvalues */
|
||||
int linedefined; /* (S) */
|
||||
int lastlinedefined; /* (S) */
|
||||
char short_src[LUA_IDSIZE]; /* (S) */
|
||||
/* private part */
|
||||
int i_ci; /* active function */
|
||||
};
|
||||
|
||||
/* }====================================================================== */
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
|
||||
*
|
||||
* 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
|
9
external/luajit/include/lua.hpp
vendored
9
external/luajit/include/lua.hpp
vendored
|
@ -1,9 +0,0 @@
|
|||
// C++ wrapper for LuaJIT header files.
|
||||
|
||||
extern "C" {
|
||||
#include "lua.h"
|
||||
#include "lauxlib.h"
|
||||
#include "lualib.h"
|
||||
#include "luajit.h"
|
||||
}
|
||||
|
152
external/luajit/include/luaconf.h
vendored
152
external/luajit/include/luaconf.h
vendored
|
@ -1,152 +0,0 @@
|
|||
/*
|
||||
** Configuration header.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef luaconf_h
|
||||
#define luaconf_h
|
||||
|
||||
#ifndef WINVER
|
||||
#define WINVER 0x0501
|
||||
#endif
|
||||
#include <limits.h>
|
||||
#include <stddef.h>
|
||||
|
||||
/* Default path for loading Lua and C modules with require(). */
|
||||
#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_PATH_DEFAULT \
|
||||
".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;"
|
||||
#define LUA_CPATH_DEFAULT \
|
||||
".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
|
||||
#else
|
||||
/*
|
||||
** Note to distribution maintainers: do NOT patch the following lines!
|
||||
** Please read ../doc/install.html#distro and pass PREFIX=/usr instead.
|
||||
*/
|
||||
#ifndef LUA_MULTILIB
|
||||
#define LUA_MULTILIB "lib"
|
||||
#endif
|
||||
#ifndef LUA_LMULTILIB
|
||||
#define LUA_LMULTILIB "lib"
|
||||
#endif
|
||||
#define LUA_LROOT "/usr/local"
|
||||
#define LUA_LUADIR "/lua/5.1/"
|
||||
#define LUA_LJDIR "/luajit-2.1.0-beta3/"
|
||||
|
||||
#ifdef LUA_ROOT
|
||||
#define LUA_JROOT LUA_ROOT
|
||||
#define LUA_RLDIR LUA_ROOT "/share" LUA_LUADIR
|
||||
#define LUA_RCDIR LUA_ROOT "/" LUA_MULTILIB LUA_LUADIR
|
||||
#define LUA_RLPATH ";" LUA_RLDIR "?.lua;" LUA_RLDIR "?/init.lua"
|
||||
#define LUA_RCPATH ";" LUA_RCDIR "?.so"
|
||||
#else
|
||||
#define LUA_JROOT LUA_LROOT
|
||||
#define LUA_RLPATH
|
||||
#define LUA_RCPATH
|
||||
#endif
|
||||
|
||||
#define LUA_JPATH ";" LUA_JROOT "/share" LUA_LJDIR "?.lua"
|
||||
#define LUA_LLDIR LUA_LROOT "/share" LUA_LUADIR
|
||||
#define LUA_LCDIR LUA_LROOT "/" LUA_LMULTILIB LUA_LUADIR
|
||||
#define LUA_LLPATH ";" LUA_LLDIR "?.lua;" LUA_LLDIR "?/init.lua"
|
||||
#define LUA_LCPATH1 ";" LUA_LCDIR "?.so"
|
||||
#define LUA_LCPATH2 ";" LUA_LCDIR "loadall.so"
|
||||
|
||||
#define LUA_PATH_DEFAULT "./?.lua" LUA_JPATH LUA_LLPATH LUA_RLPATH
|
||||
#define LUA_CPATH_DEFAULT "./?.so" LUA_LCPATH1 LUA_RCPATH LUA_LCPATH2
|
||||
#endif
|
||||
|
||||
/* Environment variable names for path overrides and initialization code. */
|
||||
#define LUA_PATH "LUA_PATH"
|
||||
#define LUA_CPATH "LUA_CPATH"
|
||||
#define LUA_INIT "LUA_INIT"
|
||||
|
||||
/* Special file system characters. */
|
||||
#if defined(_WIN32)
|
||||
#define LUA_DIRSEP "\\"
|
||||
#else
|
||||
#define LUA_DIRSEP "/"
|
||||
#endif
|
||||
#define LUA_PATHSEP ";"
|
||||
#define LUA_PATH_MARK "?"
|
||||
#define LUA_EXECDIR "!"
|
||||
#define LUA_IGMARK "-"
|
||||
#define LUA_PATH_CONFIG \
|
||||
LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" \
|
||||
LUA_EXECDIR "\n" LUA_IGMARK "\n"
|
||||
|
||||
/* Quoting in error messages. */
|
||||
#define LUA_QL(x) "'" x "'"
|
||||
#define LUA_QS LUA_QL("%s")
|
||||
|
||||
/* Various tunables. */
|
||||
#define LUAI_MAXSTACK 65500 /* Max. # of stack slots for a thread (<64K). */
|
||||
#define LUAI_MAXCSTACK 8000 /* Max. # of stack slots for a C func (<10K). */
|
||||
#define LUAI_GCPAUSE 200 /* Pause GC until memory is at 200%. */
|
||||
#define LUAI_GCMUL 200 /* Run GC at 200% of allocation speed. */
|
||||
#define LUA_MAXCAPTURES 32 /* Max. pattern captures. */
|
||||
|
||||
/* Configuration for the frontend (the luajit executable). */
|
||||
#if defined(luajit_c)
|
||||
#define LUA_PROGNAME "luajit" /* Fallback frontend name. */
|
||||
#define LUA_PROMPT "> " /* Interactive prompt. */
|
||||
#define LUA_PROMPT2 ">> " /* Continuation prompt. */
|
||||
#define LUA_MAXINPUT 512 /* Max. input line length. */
|
||||
#endif
|
||||
|
||||
/* Note: changing the following defines breaks the Lua 5.1 ABI. */
|
||||
#define LUA_INTEGER ptrdiff_t
|
||||
#define LUA_IDSIZE 60 /* Size of lua_Debug.short_src. */
|
||||
/*
|
||||
** Size of lauxlib and io.* on-stack buffers. Weird workaround to avoid using
|
||||
** unreasonable amounts of stack space, but still retain ABI compatibility.
|
||||
** Blame Lua for depending on BUFSIZ in the ABI, blame **** for wrecking it.
|
||||
*/
|
||||
#define LUAL_BUFFERSIZE (BUFSIZ > 16384 ? 8192 : BUFSIZ)
|
||||
|
||||
/* The following defines are here only for compatibility with luaconf.h
|
||||
** from the standard Lua distribution. They must not be changed for LuaJIT.
|
||||
*/
|
||||
#define LUA_NUMBER_DOUBLE
|
||||
#define LUA_NUMBER double
|
||||
#define LUAI_UACNUMBER double
|
||||
#define LUA_NUMBER_SCAN "%lf"
|
||||
#define LUA_NUMBER_FMT "%.14g"
|
||||
#define lua_number2str(s, n) sprintf((s), LUA_NUMBER_FMT, (n))
|
||||
#define LUAI_MAXNUMBER2STR 32
|
||||
#define LUA_INTFRMLEN "l"
|
||||
#define LUA_INTFRM_T long
|
||||
|
||||
/* Linkage of public API functions. */
|
||||
#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
|
||||
|
||||
#define LUALIB_API LUA_API
|
||||
|
||||
/* Support for internal assertions. */
|
||||
#if defined(LUA_USE_ASSERT) || defined(LUA_USE_APICHECK)
|
||||
#include <assert.h>
|
||||
#endif
|
||||
#ifdef LUA_USE_ASSERT
|
||||
#define lua_assert(x) assert(x)
|
||||
#endif
|
||||
#ifdef LUA_USE_APICHECK
|
||||
#define luai_apicheck(L, o) { (void)L; assert(o); }
|
||||
#else
|
||||
#define luai_apicheck(L, o) { (void)L; }
|
||||
#endif
|
||||
|
||||
#endif
|
79
external/luajit/include/luajit.h
vendored
79
external/luajit/include/luajit.h
vendored
|
@ -1,79 +0,0 @@
|
|||
/*
|
||||
** LuaJIT -- a Just-In-Time Compiler for Lua. http://luajit.org/
|
||||
**
|
||||
** Copyright (C) 2005-2017 Mike Pall. All rights reserved.
|
||||
**
|
||||
** 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.
|
||||
**
|
||||
** [ MIT license: http://www.opensource.org/licenses/mit-license.php ]
|
||||
*/
|
||||
|
||||
#ifndef _LUAJIT_H
|
||||
#define _LUAJIT_H
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUAJIT_VERSION "LuaJIT 2.1.0-beta3"
|
||||
#define LUAJIT_VERSION_NUM 20100 /* Version 2.1.0 = 02.01.00. */
|
||||
#define LUAJIT_VERSION_SYM luaJIT_version_2_1_0_beta3
|
||||
#define LUAJIT_COPYRIGHT "Copyright (C) 2005-2017 Mike Pall"
|
||||
#define LUAJIT_URL "http://luajit.org/"
|
||||
|
||||
/* Modes for luaJIT_setmode. */
|
||||
#define LUAJIT_MODE_MASK 0x00ff
|
||||
|
||||
enum {
|
||||
LUAJIT_MODE_ENGINE, /* Set mode for whole JIT engine. */
|
||||
LUAJIT_MODE_DEBUG, /* Set debug mode (idx = level). */
|
||||
|
||||
LUAJIT_MODE_FUNC, /* Change mode for a function. */
|
||||
LUAJIT_MODE_ALLFUNC, /* Recurse into subroutine protos. */
|
||||
LUAJIT_MODE_ALLSUBFUNC, /* Change only the subroutines. */
|
||||
|
||||
LUAJIT_MODE_TRACE, /* Flush a compiled trace. */
|
||||
|
||||
LUAJIT_MODE_WRAPCFUNC = 0x10, /* Set wrapper mode for C function calls. */
|
||||
|
||||
LUAJIT_MODE_MAX
|
||||
};
|
||||
|
||||
/* Flags or'ed in to the mode. */
|
||||
#define LUAJIT_MODE_OFF 0x0000 /* Turn feature off. */
|
||||
#define LUAJIT_MODE_ON 0x0100 /* Turn feature on. */
|
||||
#define LUAJIT_MODE_FLUSH 0x0200 /* Flush JIT-compiled code. */
|
||||
|
||||
/* LuaJIT public C API. */
|
||||
|
||||
/* Control the JIT engine. */
|
||||
LUA_API int luaJIT_setmode(lua_State *L, int idx, int mode);
|
||||
|
||||
/* Low-overhead profiling API. */
|
||||
typedef void (*luaJIT_profile_callback)(void *data, lua_State *L,
|
||||
int samples, int vmstate);
|
||||
LUA_API void luaJIT_profile_start(lua_State *L, const char *mode,
|
||||
luaJIT_profile_callback cb, void *data);
|
||||
LUA_API void luaJIT_profile_stop(lua_State *L);
|
||||
LUA_API const char *luaJIT_profile_dumpstack(lua_State *L, const char *fmt,
|
||||
int depth, size_t *len);
|
||||
|
||||
/* Enforce (dynamic) linker error for version mismatches. Call from main. */
|
||||
LUA_API void LUAJIT_VERSION_SYM(void);
|
||||
|
||||
#endif
|
43
external/luajit/include/lualib.h
vendored
43
external/luajit/include/lualib.h
vendored
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
** Standard library header.
|
||||
** Copyright (C) 2005-2017 Mike Pall. See Copyright Notice in luajit.h
|
||||
*/
|
||||
|
||||
#ifndef _LUALIB_H
|
||||
#define _LUALIB_H
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define LUA_FILEHANDLE "FILE*"
|
||||
|
||||
#define LUA_COLIBNAME "coroutine"
|
||||
#define LUA_MATHLIBNAME "math"
|
||||
#define LUA_STRLIBNAME "string"
|
||||
#define LUA_TABLIBNAME "table"
|
||||
#define LUA_IOLIBNAME "io"
|
||||
#define LUA_OSLIBNAME "os"
|
||||
#define LUA_LOADLIBNAME "package"
|
||||
#define LUA_DBLIBNAME "debug"
|
||||
#define LUA_BITLIBNAME "bit"
|
||||
#define LUA_JITLIBNAME "jit"
|
||||
#define LUA_FFILIBNAME "ffi"
|
||||
|
||||
LUALIB_API int luaopen_base(lua_State *L);
|
||||
LUALIB_API int luaopen_math(lua_State *L);
|
||||
LUALIB_API int luaopen_string(lua_State *L);
|
||||
LUALIB_API int luaopen_table(lua_State *L);
|
||||
LUALIB_API int luaopen_io(lua_State *L);
|
||||
LUALIB_API int luaopen_os(lua_State *L);
|
||||
LUALIB_API int luaopen_package(lua_State *L);
|
||||
LUALIB_API int luaopen_debug(lua_State *L);
|
||||
LUALIB_API int luaopen_bit(lua_State *L);
|
||||
LUALIB_API int luaopen_jit(lua_State *L);
|
||||
LUALIB_API int luaopen_ffi(lua_State *L);
|
||||
|
||||
LUALIB_API void luaL_openlibs(lua_State *L);
|
||||
|
||||
#ifndef lua_assert
|
||||
#define lua_assert(x) ((void)0)
|
||||
#endif
|
||||
|
||||
#endif
|
BIN
external/luajit/lib/win64_vs2017/release/lua51.lib
vendored
BIN
external/luajit/lib/win64_vs2017/release/lua51.lib
vendored
Binary file not shown.
BIN
external/luajit/lib/win64_vs2017/release/luajit.lib
vendored
BIN
external/luajit/lib/win64_vs2017/release/luajit.lib
vendored
Binary file not shown.
59
external/luau/include/Luau/AddressA64.h
vendored
Normal file
59
external/luau/include/Luau/AddressA64.h
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/RegisterA64.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace A64
|
||||
{
|
||||
|
||||
enum class AddressKindA64 : uint8_t
|
||||
{
|
||||
reg, // reg + reg
|
||||
imm, // reg + imm
|
||||
pre, // reg + imm, reg += imm
|
||||
post, // reg, reg += imm
|
||||
};
|
||||
|
||||
struct AddressA64
|
||||
{
|
||||
// This is a little misleading since AddressA64 can encode offsets up to 1023*size where size depends on the load/store size
|
||||
// For example, ldr x0, [reg+imm] is limited to 8 KB offsets assuming imm is divisible by 8, but loading into w0 reduces the range to 4 KB
|
||||
static constexpr size_t kMaxOffset = 1023;
|
||||
|
||||
constexpr AddressA64(RegisterA64 base, int off = 0, AddressKindA64 kind = AddressKindA64::imm)
|
||||
: kind(kind)
|
||||
, base(base)
|
||||
, offset(xzr)
|
||||
, data(off)
|
||||
{
|
||||
LUAU_ASSERT(base.kind == KindA64::x || base == sp);
|
||||
LUAU_ASSERT(kind != AddressKindA64::reg);
|
||||
}
|
||||
|
||||
constexpr AddressA64(RegisterA64 base, RegisterA64 offset)
|
||||
: kind(AddressKindA64::reg)
|
||||
, base(base)
|
||||
, offset(offset)
|
||||
, data(0)
|
||||
{
|
||||
LUAU_ASSERT(base.kind == KindA64::x);
|
||||
LUAU_ASSERT(offset.kind == KindA64::x);
|
||||
}
|
||||
|
||||
AddressKindA64 kind;
|
||||
RegisterA64 base;
|
||||
RegisterA64 offset;
|
||||
int data;
|
||||
};
|
||||
|
||||
using mem = AddressA64;
|
||||
|
||||
} // namespace A64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
283
external/luau/include/Luau/AssemblyBuilderA64.h
vendored
Normal file
283
external/luau/include/Luau/AssemblyBuilderA64.h
vendored
Normal file
|
@ -0,0 +1,283 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/RegisterA64.h"
|
||||
#include "Luau/AddressA64.h"
|
||||
#include "Luau/ConditionA64.h"
|
||||
#include "Luau/Label.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace A64
|
||||
{
|
||||
|
||||
enum FeaturesA64
|
||||
{
|
||||
Feature_JSCVT = 1 << 0,
|
||||
};
|
||||
|
||||
class AssemblyBuilderA64
|
||||
{
|
||||
public:
|
||||
explicit AssemblyBuilderA64(bool logText, unsigned int features = 0);
|
||||
~AssemblyBuilderA64();
|
||||
|
||||
// Moves
|
||||
void mov(RegisterA64 dst, RegisterA64 src);
|
||||
void mov(RegisterA64 dst, int src); // macro
|
||||
|
||||
// Moves of 32-bit immediates get decomposed into one or more of these
|
||||
void movz(RegisterA64 dst, uint16_t src, int shift = 0);
|
||||
void movn(RegisterA64 dst, uint16_t src, int shift = 0);
|
||||
void movk(RegisterA64 dst, uint16_t src, int shift = 0);
|
||||
|
||||
// Arithmetics
|
||||
void add(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void add(RegisterA64 dst, RegisterA64 src1, uint16_t src2);
|
||||
void sub(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void sub(RegisterA64 dst, RegisterA64 src1, uint16_t src2);
|
||||
void neg(RegisterA64 dst, RegisterA64 src);
|
||||
|
||||
// Comparisons
|
||||
// Note: some arithmetic instructions also have versions that update flags (ADDS etc) but we aren't using them atm
|
||||
void cmp(RegisterA64 src1, RegisterA64 src2);
|
||||
void cmp(RegisterA64 src1, uint16_t src2);
|
||||
void csel(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, ConditionA64 cond);
|
||||
void cset(RegisterA64 dst, ConditionA64 cond);
|
||||
|
||||
// Bitwise
|
||||
void and_(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void orr(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void eor(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void bic(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void tst(RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
void mvn_(RegisterA64 dst, RegisterA64 src);
|
||||
|
||||
// Bitwise with immediate
|
||||
// Note: immediate must have a single contiguous sequence of 1 bits set of length 1..31
|
||||
void and_(RegisterA64 dst, RegisterA64 src1, uint32_t src2);
|
||||
void orr(RegisterA64 dst, RegisterA64 src1, uint32_t src2);
|
||||
void eor(RegisterA64 dst, RegisterA64 src1, uint32_t src2);
|
||||
void tst(RegisterA64 src1, uint32_t src2);
|
||||
|
||||
// Shifts
|
||||
void lsl(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void lsr(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void asr(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void ror(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void clz(RegisterA64 dst, RegisterA64 src);
|
||||
void rbit(RegisterA64 dst, RegisterA64 src);
|
||||
|
||||
// Shifts with immediates
|
||||
// Note: immediate value must be in [0, 31] or [0, 63] range based on register type
|
||||
void lsl(RegisterA64 dst, RegisterA64 src1, uint8_t src2);
|
||||
void lsr(RegisterA64 dst, RegisterA64 src1, uint8_t src2);
|
||||
void asr(RegisterA64 dst, RegisterA64 src1, uint8_t src2);
|
||||
void ror(RegisterA64 dst, RegisterA64 src1, uint8_t src2);
|
||||
|
||||
// Bitfields
|
||||
void ubfiz(RegisterA64 dst, RegisterA64 src, uint8_t f, uint8_t w);
|
||||
void ubfx(RegisterA64 dst, RegisterA64 src, uint8_t f, uint8_t w);
|
||||
void sbfiz(RegisterA64 dst, RegisterA64 src, uint8_t f, uint8_t w);
|
||||
void sbfx(RegisterA64 dst, RegisterA64 src, uint8_t f, uint8_t w);
|
||||
|
||||
// Load
|
||||
// Note: paired loads are currently omitted for simplicity
|
||||
void ldr(RegisterA64 dst, AddressA64 src);
|
||||
void ldrb(RegisterA64 dst, AddressA64 src);
|
||||
void ldrh(RegisterA64 dst, AddressA64 src);
|
||||
void ldrsb(RegisterA64 dst, AddressA64 src);
|
||||
void ldrsh(RegisterA64 dst, AddressA64 src);
|
||||
void ldrsw(RegisterA64 dst, AddressA64 src);
|
||||
void ldp(RegisterA64 dst1, RegisterA64 dst2, AddressA64 src);
|
||||
|
||||
// Store
|
||||
void str(RegisterA64 src, AddressA64 dst);
|
||||
void strb(RegisterA64 src, AddressA64 dst);
|
||||
void strh(RegisterA64 src, AddressA64 dst);
|
||||
void stp(RegisterA64 src1, RegisterA64 src2, AddressA64 dst);
|
||||
|
||||
// Control flow
|
||||
void b(Label& label);
|
||||
void bl(Label& label);
|
||||
void br(RegisterA64 src);
|
||||
void blr(RegisterA64 src);
|
||||
void ret();
|
||||
|
||||
// Conditional control flow
|
||||
void b(ConditionA64 cond, Label& label);
|
||||
void cbz(RegisterA64 src, Label& label);
|
||||
void cbnz(RegisterA64 src, Label& label);
|
||||
void tbz(RegisterA64 src, uint8_t bit, Label& label);
|
||||
void tbnz(RegisterA64 src, uint8_t bit, Label& label);
|
||||
|
||||
// Address of embedded data
|
||||
void adr(RegisterA64 dst, const void* ptr, size_t size);
|
||||
void adr(RegisterA64 dst, uint64_t value);
|
||||
void adr(RegisterA64 dst, double value);
|
||||
|
||||
// Address of code (label)
|
||||
void adr(RegisterA64 dst, Label& label);
|
||||
|
||||
// Floating-point scalar moves
|
||||
// Note: constant must be compatible with immediate floating point moves (see isFmovSupported)
|
||||
void fmov(RegisterA64 dst, RegisterA64 src);
|
||||
void fmov(RegisterA64 dst, double src);
|
||||
|
||||
// Floating-point scalar math
|
||||
void fabs(RegisterA64 dst, RegisterA64 src);
|
||||
void fadd(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void fdiv(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void fmul(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
void fneg(RegisterA64 dst, RegisterA64 src);
|
||||
void fsqrt(RegisterA64 dst, RegisterA64 src);
|
||||
void fsub(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2);
|
||||
|
||||
// Floating-point rounding and conversions
|
||||
void frinta(RegisterA64 dst, RegisterA64 src);
|
||||
void frintm(RegisterA64 dst, RegisterA64 src);
|
||||
void frintp(RegisterA64 dst, RegisterA64 src);
|
||||
void fcvt(RegisterA64 dst, RegisterA64 src);
|
||||
void fcvtzs(RegisterA64 dst, RegisterA64 src);
|
||||
void fcvtzu(RegisterA64 dst, RegisterA64 src);
|
||||
void scvtf(RegisterA64 dst, RegisterA64 src);
|
||||
void ucvtf(RegisterA64 dst, RegisterA64 src);
|
||||
|
||||
// Floating-point conversion to integer using JS rules (wrap around 2^32) and set Z flag
|
||||
// note: this is part of ARM8.3 (JSCVT feature); support of this instruction needs to be checked at runtime
|
||||
void fjcvtzs(RegisterA64 dst, RegisterA64 src);
|
||||
|
||||
// Floating-point comparisons
|
||||
void fcmp(RegisterA64 src1, RegisterA64 src2);
|
||||
void fcmpz(RegisterA64 src);
|
||||
void fcsel(RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, ConditionA64 cond);
|
||||
|
||||
void udf();
|
||||
|
||||
// Run final checks
|
||||
bool finalize();
|
||||
|
||||
// Places a label at current location and returns it
|
||||
Label setLabel();
|
||||
|
||||
// Assigns label position to the current location
|
||||
void setLabel(Label& label);
|
||||
|
||||
// Extracts code offset (in bytes) from label
|
||||
uint32_t getLabelOffset(const Label& label)
|
||||
{
|
||||
LUAU_ASSERT(label.location != ~0u);
|
||||
return label.location * 4;
|
||||
}
|
||||
|
||||
void logAppend(const char* fmt, ...) LUAU_PRINTF_ATTR(2, 3);
|
||||
|
||||
uint32_t getCodeSize() const;
|
||||
|
||||
// Resulting data and code that need to be copied over one after the other
|
||||
// The *end* of 'data' has to be aligned to 16 bytes, this will also align 'code'
|
||||
std::vector<uint8_t> data;
|
||||
std::vector<uint32_t> code;
|
||||
|
||||
std::string text;
|
||||
|
||||
const bool logText = false;
|
||||
const unsigned int features = 0;
|
||||
|
||||
// Maximum immediate argument to functions like add/sub/cmp
|
||||
static constexpr size_t kMaxImmediate = (1 << 12) - 1;
|
||||
|
||||
// Check if immediate mode mask is supported for bitwise operations (and/or/xor)
|
||||
static bool isMaskSupported(uint32_t mask);
|
||||
|
||||
// Check if fmov can be used to synthesize a constant
|
||||
static bool isFmovSupported(double value);
|
||||
|
||||
private:
|
||||
// Instruction archetypes
|
||||
void place0(const char* name, uint32_t word);
|
||||
void placeSR3(const char* name, RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, uint8_t op, int shift = 0, int N = 0);
|
||||
void placeSR2(const char* name, RegisterA64 dst, RegisterA64 src, uint8_t op, uint8_t op2 = 0);
|
||||
void placeR3(const char* name, RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, uint8_t op, uint8_t op2);
|
||||
void placeR1(const char* name, RegisterA64 dst, RegisterA64 src, uint32_t op);
|
||||
void placeI12(const char* name, RegisterA64 dst, RegisterA64 src1, int src2, uint8_t op);
|
||||
void placeI16(const char* name, RegisterA64 dst, int src, uint8_t op, int shift = 0);
|
||||
void placeA(const char* name, RegisterA64 dst, AddressA64 src, uint16_t opsize, int sizelog);
|
||||
void placeB(const char* name, Label& label, uint8_t op);
|
||||
void placeBC(const char* name, Label& label, uint8_t op, uint8_t cond);
|
||||
void placeBCR(const char* name, Label& label, uint8_t op, RegisterA64 cond);
|
||||
void placeBR(const char* name, RegisterA64 src, uint32_t op);
|
||||
void placeBTR(const char* name, Label& label, uint8_t op, RegisterA64 cond, uint8_t bit);
|
||||
void placeADR(const char* name, RegisterA64 src, uint8_t op);
|
||||
void placeADR(const char* name, RegisterA64 src, uint8_t op, Label& label);
|
||||
void placeP(const char* name, RegisterA64 dst1, RegisterA64 dst2, AddressA64 src, uint8_t op, uint8_t opc, int sizelog);
|
||||
void placeCS(const char* name, RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, ConditionA64 cond, uint8_t op, uint8_t opc, int invert = 0);
|
||||
void placeFCMP(const char* name, RegisterA64 src1, RegisterA64 src2, uint8_t op, uint8_t opc);
|
||||
void placeFMOV(const char* name, RegisterA64 dst, double src, uint32_t op);
|
||||
void placeBM(const char* name, RegisterA64 dst, RegisterA64 src1, uint32_t src2, uint8_t op);
|
||||
void placeBFM(const char* name, RegisterA64 dst, RegisterA64 src1, int src2, uint8_t op, int immr, int imms);
|
||||
void placeER(const char* name, RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, uint8_t op, int shift);
|
||||
|
||||
void place(uint32_t word);
|
||||
|
||||
struct Patch
|
||||
{
|
||||
enum Kind
|
||||
{
|
||||
Imm26,
|
||||
Imm19,
|
||||
Imm14,
|
||||
};
|
||||
|
||||
Kind kind : 2;
|
||||
uint32_t label : 30;
|
||||
uint32_t location;
|
||||
};
|
||||
|
||||
void patchLabel(Label& label, Patch::Kind kind);
|
||||
void patchOffset(uint32_t location, int value, Patch::Kind kind);
|
||||
|
||||
void commit();
|
||||
LUAU_NOINLINE void extend();
|
||||
|
||||
// Data
|
||||
size_t allocateData(size_t size, size_t align);
|
||||
|
||||
// Logging of assembly in text form
|
||||
LUAU_NOINLINE void log(const char* opcode);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, int shift = 0);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, RegisterA64 src1, int src2);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, RegisterA64 src);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, int src, int shift = 0);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, double src);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, AddressA64 src);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst1, RegisterA64 dst2, AddressA64 src);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 src, Label label, int imm = -1);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 src);
|
||||
LUAU_NOINLINE void log(const char* opcode, Label label);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterA64 dst, RegisterA64 src1, RegisterA64 src2, ConditionA64 cond);
|
||||
LUAU_NOINLINE void log(Label label);
|
||||
LUAU_NOINLINE void log(RegisterA64 reg);
|
||||
LUAU_NOINLINE void log(AddressA64 addr);
|
||||
|
||||
uint32_t nextLabel = 1;
|
||||
std::vector<Patch> pendingLabels;
|
||||
std::vector<uint32_t> labelLocations;
|
||||
|
||||
bool finalized = false;
|
||||
bool overflowed = false;
|
||||
|
||||
size_t dataPos = 0;
|
||||
|
||||
uint32_t* codePos = nullptr;
|
||||
uint32_t* codeEnd = nullptr;
|
||||
};
|
||||
|
||||
} // namespace A64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
270
external/luau/include/Luau/AssemblyBuilderX64.h
vendored
Normal file
270
external/luau/include/Luau/AssemblyBuilderX64.h
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
#include "Luau/DenseHash.h"
|
||||
#include "Luau/Label.h"
|
||||
#include "Luau/ConditionX64.h"
|
||||
#include "Luau/OperandX64.h"
|
||||
#include "Luau/RegisterX64.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace X64
|
||||
{
|
||||
|
||||
enum class RoundingModeX64
|
||||
{
|
||||
RoundToNearestEven = 0b00,
|
||||
RoundToNegativeInfinity = 0b01,
|
||||
RoundToPositiveInfinity = 0b10,
|
||||
RoundToZero = 0b11,
|
||||
};
|
||||
|
||||
enum class AlignmentDataX64
|
||||
{
|
||||
Nop,
|
||||
Int3,
|
||||
Ud2, // int3 will be used as a fall-back if it doesn't fit
|
||||
};
|
||||
|
||||
enum class ABIX64
|
||||
{
|
||||
Windows,
|
||||
SystemV,
|
||||
};
|
||||
|
||||
class AssemblyBuilderX64
|
||||
{
|
||||
public:
|
||||
explicit AssemblyBuilderX64(bool logText, ABIX64 abi);
|
||||
explicit AssemblyBuilderX64(bool logText);
|
||||
~AssemblyBuilderX64();
|
||||
|
||||
// Base two operand instructions with 9 opcode selection
|
||||
void add(OperandX64 lhs, OperandX64 rhs);
|
||||
void sub(OperandX64 lhs, OperandX64 rhs);
|
||||
void cmp(OperandX64 lhs, OperandX64 rhs);
|
||||
void and_(OperandX64 lhs, OperandX64 rhs);
|
||||
void or_(OperandX64 lhs, OperandX64 rhs);
|
||||
void xor_(OperandX64 lhs, OperandX64 rhs);
|
||||
|
||||
// Binary shift instructions with special rhs handling
|
||||
void sal(OperandX64 lhs, OperandX64 rhs);
|
||||
void sar(OperandX64 lhs, OperandX64 rhs);
|
||||
void shl(OperandX64 lhs, OperandX64 rhs);
|
||||
void shr(OperandX64 lhs, OperandX64 rhs);
|
||||
void rol(OperandX64 lhs, OperandX64 rhs);
|
||||
void ror(OperandX64 lhs, OperandX64 rhs);
|
||||
|
||||
// Two operand mov instruction has additional specialized encodings
|
||||
void mov(OperandX64 lhs, OperandX64 rhs);
|
||||
void mov64(RegisterX64 lhs, int64_t imm);
|
||||
void movsx(RegisterX64 lhs, OperandX64 rhs);
|
||||
void movzx(RegisterX64 lhs, OperandX64 rhs);
|
||||
|
||||
// Base one operand instruction with 2 opcode selection
|
||||
void div(OperandX64 op);
|
||||
void idiv(OperandX64 op);
|
||||
void mul(OperandX64 op);
|
||||
void imul(OperandX64 op);
|
||||
void neg(OperandX64 op);
|
||||
void not_(OperandX64 op);
|
||||
void dec(OperandX64 op);
|
||||
void inc(OperandX64 op);
|
||||
|
||||
// Additional forms of imul
|
||||
void imul(OperandX64 lhs, OperandX64 rhs);
|
||||
void imul(OperandX64 dst, OperandX64 lhs, int32_t rhs);
|
||||
|
||||
void test(OperandX64 lhs, OperandX64 rhs);
|
||||
void lea(OperandX64 lhs, OperandX64 rhs);
|
||||
void setcc(ConditionX64 cond, OperandX64 op);
|
||||
|
||||
void push(OperandX64 op);
|
||||
void pop(OperandX64 op);
|
||||
void ret();
|
||||
|
||||
// Control flow
|
||||
void jcc(ConditionX64 cond, Label& label);
|
||||
void jmp(Label& label);
|
||||
void jmp(OperandX64 op);
|
||||
|
||||
void call(Label& label);
|
||||
void call(OperandX64 op);
|
||||
|
||||
void lea(RegisterX64 lhs, Label& label);
|
||||
|
||||
void int3();
|
||||
void ud2();
|
||||
|
||||
void bsr(RegisterX64 dst, OperandX64 src);
|
||||
void bsf(RegisterX64 dst, OperandX64 src);
|
||||
|
||||
// Code alignment
|
||||
void nop(uint32_t length = 1);
|
||||
void align(uint32_t alignment, AlignmentDataX64 data = AlignmentDataX64::Nop);
|
||||
|
||||
// AVX
|
||||
void vaddpd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vaddps(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vaddsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vaddss(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vsubsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vmulsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vdivsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vandpd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vandnpd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vxorpd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vorpd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vucomisd(OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vcvttsd2si(OperandX64 dst, OperandX64 src);
|
||||
void vcvtsi2sd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vcvtsd2ss(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vroundsd(OperandX64 dst, OperandX64 src1, OperandX64 src2, RoundingModeX64 roundingMode); // inexact
|
||||
|
||||
void vsqrtpd(OperandX64 dst, OperandX64 src);
|
||||
void vsqrtps(OperandX64 dst, OperandX64 src);
|
||||
void vsqrtsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vsqrtss(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vmovsd(OperandX64 dst, OperandX64 src);
|
||||
void vmovsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vmovss(OperandX64 dst, OperandX64 src);
|
||||
void vmovss(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vmovapd(OperandX64 dst, OperandX64 src);
|
||||
void vmovaps(OperandX64 dst, OperandX64 src);
|
||||
void vmovupd(OperandX64 dst, OperandX64 src);
|
||||
void vmovups(OperandX64 dst, OperandX64 src);
|
||||
void vmovq(OperandX64 lhs, OperandX64 rhs);
|
||||
|
||||
void vmaxsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
void vminsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vcmpltsd(OperandX64 dst, OperandX64 src1, OperandX64 src2);
|
||||
|
||||
void vblendvpd(RegisterX64 dst, RegisterX64 src1, OperandX64 mask, RegisterX64 src3);
|
||||
|
||||
|
||||
// Run final checks
|
||||
bool finalize();
|
||||
|
||||
// Places a label at current location and returns it
|
||||
Label setLabel();
|
||||
|
||||
// Assigns label position to the current location
|
||||
void setLabel(Label& label);
|
||||
|
||||
// Extracts code offset (in bytes) from label
|
||||
uint32_t getLabelOffset(const Label& label)
|
||||
{
|
||||
LUAU_ASSERT(label.location != ~0u);
|
||||
return label.location;
|
||||
}
|
||||
|
||||
// Constant allocation (uses rip-relative addressing)
|
||||
OperandX64 i64(int64_t value);
|
||||
OperandX64 f32(float value);
|
||||
OperandX64 f64(double value);
|
||||
OperandX64 f32x4(float x, float y, float z, float w);
|
||||
OperandX64 f64x2(double x, double y);
|
||||
OperandX64 bytes(const void* ptr, size_t size, size_t align = 8);
|
||||
|
||||
void logAppend(const char* fmt, ...) LUAU_PRINTF_ATTR(2, 3);
|
||||
|
||||
uint32_t getCodeSize() const;
|
||||
|
||||
// Resulting data and code that need to be copied over one after the other
|
||||
// The *end* of 'data' has to be aligned to 16 bytes, this will also align 'code'
|
||||
std::vector<uint8_t> data;
|
||||
std::vector<uint8_t> code;
|
||||
|
||||
std::string text;
|
||||
|
||||
const bool logText = false;
|
||||
|
||||
const ABIX64 abi;
|
||||
|
||||
private:
|
||||
// Instruction archetypes
|
||||
void placeBinary(const char* name, OperandX64 lhs, OperandX64 rhs, uint8_t codeimm8, uint8_t codeimm, uint8_t codeimmImm8, uint8_t code8rev,
|
||||
uint8_t coderev, uint8_t code8, uint8_t code, uint8_t opreg);
|
||||
void placeBinaryRegMemAndImm(OperandX64 lhs, OperandX64 rhs, uint8_t code8, uint8_t code, uint8_t codeImm8, uint8_t opreg);
|
||||
void placeBinaryRegAndRegMem(OperandX64 lhs, OperandX64 rhs, uint8_t code8, uint8_t code);
|
||||
void placeBinaryRegMemAndReg(OperandX64 lhs, OperandX64 rhs, uint8_t code8, uint8_t code);
|
||||
|
||||
void placeUnaryModRegMem(const char* name, OperandX64 op, uint8_t code8, uint8_t code, uint8_t opreg);
|
||||
|
||||
void placeShift(const char* name, OperandX64 lhs, OperandX64 rhs, uint8_t opreg);
|
||||
|
||||
void placeJcc(const char* name, Label& label, uint8_t cc);
|
||||
|
||||
void placeAvx(const char* name, OperandX64 dst, OperandX64 src, uint8_t code, bool setW, uint8_t mode, uint8_t prefix);
|
||||
void placeAvx(const char* name, OperandX64 dst, OperandX64 src, uint8_t code, uint8_t coderev, bool setW, uint8_t mode, uint8_t prefix);
|
||||
void placeAvx(const char* name, OperandX64 dst, OperandX64 src1, OperandX64 src2, uint8_t code, bool setW, uint8_t mode, uint8_t prefix);
|
||||
void placeAvx(
|
||||
const char* name, OperandX64 dst, OperandX64 src1, OperandX64 src2, uint8_t imm8, uint8_t code, bool setW, uint8_t mode, uint8_t prefix);
|
||||
|
||||
// Instruction components
|
||||
void placeRegAndModRegMem(OperandX64 lhs, OperandX64 rhs, int32_t extraCodeBytes = 0);
|
||||
void placeModRegMem(OperandX64 rhs, uint8_t regop, int32_t extraCodeBytes = 0);
|
||||
void placeRex(RegisterX64 op);
|
||||
void placeRex(OperandX64 op);
|
||||
void placeRexNoW(OperandX64 op);
|
||||
void placeRex(RegisterX64 lhs, OperandX64 rhs);
|
||||
void placeVex(OperandX64 dst, OperandX64 src1, OperandX64 src2, bool setW, uint8_t mode, uint8_t prefix);
|
||||
void placeImm8Or32(int32_t imm);
|
||||
void placeImm8(int32_t imm);
|
||||
void placeImm32(int32_t imm);
|
||||
void placeImm64(int64_t imm);
|
||||
void placeLabel(Label& label);
|
||||
void place(uint8_t byte);
|
||||
|
||||
void commit();
|
||||
LUAU_NOINLINE void extend();
|
||||
|
||||
// Data
|
||||
size_t allocateData(size_t size, size_t align);
|
||||
|
||||
// Logging of assembly in text form (Intel asm with VS disassembly formatting)
|
||||
LUAU_NOINLINE void log(const char* opcode);
|
||||
LUAU_NOINLINE void log(const char* opcode, OperandX64 op);
|
||||
LUAU_NOINLINE void log(const char* opcode, OperandX64 op1, OperandX64 op2);
|
||||
LUAU_NOINLINE void log(const char* opcode, OperandX64 op1, OperandX64 op2, OperandX64 op3);
|
||||
LUAU_NOINLINE void log(const char* opcode, OperandX64 op1, OperandX64 op2, OperandX64 op3, OperandX64 op4);
|
||||
LUAU_NOINLINE void log(Label label);
|
||||
LUAU_NOINLINE void log(const char* opcode, Label label);
|
||||
LUAU_NOINLINE void log(const char* opcode, RegisterX64 reg, Label label);
|
||||
void log(OperandX64 op);
|
||||
|
||||
const char* getSizeName(SizeX64 size) const;
|
||||
const char* getRegisterName(RegisterX64 reg) const;
|
||||
|
||||
uint32_t nextLabel = 1;
|
||||
std::vector<Label> pendingLabels;
|
||||
std::vector<uint32_t> labelLocations;
|
||||
|
||||
DenseHashMap<uint64_t, int32_t> constCache64;
|
||||
|
||||
bool finalized = false;
|
||||
|
||||
size_t dataPos = 0;
|
||||
|
||||
uint8_t* codePos = nullptr;
|
||||
uint8_t* codeEnd = nullptr;
|
||||
};
|
||||
|
||||
} // namespace X64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
1330
external/luau/include/Luau/Ast.h
vendored
Normal file
1330
external/luau/include/Luau/Ast.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
285
external/luau/include/Luau/BytecodeBuilder.h
vendored
Normal file
285
external/luau/include/Luau/BytecodeBuilder.h
vendored
Normal file
|
@ -0,0 +1,285 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Bytecode.h"
|
||||
#include "Luau/DenseHash.h"
|
||||
#include "Luau/StringUtils.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
class BytecodeEncoder
|
||||
{
|
||||
public:
|
||||
virtual ~BytecodeEncoder() {}
|
||||
|
||||
virtual void encode(uint32_t* data, size_t count) = 0;
|
||||
};
|
||||
|
||||
class BytecodeBuilder
|
||||
{
|
||||
public:
|
||||
// BytecodeBuilder does *not* copy the data passed via StringRef; instead, it keeps the ref around until finalize()
|
||||
// Please be careful with the lifetime of the data that's being passed because of this.
|
||||
// The safe and correct pattern is to only build StringRefs out of pieces of AST (AstName or AstArray<>) that are backed by AstAllocator.
|
||||
// Note that you must finalize() the builder before the Allocator backing the Ast is destroyed.
|
||||
struct StringRef
|
||||
{
|
||||
// To construct a StringRef, use sref() from Compiler.cpp.
|
||||
const char* data = nullptr;
|
||||
size_t length = 0;
|
||||
|
||||
bool operator==(const StringRef& other) const;
|
||||
};
|
||||
|
||||
struct TableShape
|
||||
{
|
||||
static const unsigned int kMaxLength = 32;
|
||||
|
||||
int32_t keys[kMaxLength];
|
||||
unsigned int length = 0;
|
||||
|
||||
bool operator==(const TableShape& other) const;
|
||||
};
|
||||
|
||||
BytecodeBuilder(BytecodeEncoder* encoder = 0);
|
||||
|
||||
uint32_t beginFunction(uint8_t numparams, bool isvararg = false);
|
||||
void endFunction(uint8_t maxstacksize, uint8_t numupvalues, uint8_t flags = 0);
|
||||
|
||||
void setMainFunction(uint32_t fid);
|
||||
|
||||
int32_t addConstantNil();
|
||||
int32_t addConstantBoolean(bool value);
|
||||
int32_t addConstantNumber(double value);
|
||||
int32_t addConstantString(StringRef value);
|
||||
int32_t addImport(uint32_t iid);
|
||||
int32_t addConstantTable(const TableShape& shape);
|
||||
int32_t addConstantClosure(uint32_t fid);
|
||||
|
||||
int16_t addChildFunction(uint32_t fid);
|
||||
|
||||
void emitABC(LuauOpcode op, uint8_t a, uint8_t b, uint8_t c);
|
||||
void emitAD(LuauOpcode op, uint8_t a, int16_t d);
|
||||
void emitE(LuauOpcode op, int32_t e);
|
||||
void emitAux(uint32_t aux);
|
||||
|
||||
size_t emitLabel();
|
||||
|
||||
[[nodiscard]] bool patchJumpD(size_t jumpLabel, size_t targetLabel);
|
||||
[[nodiscard]] bool patchSkipC(size_t jumpLabel, size_t targetLabel);
|
||||
|
||||
void foldJumps();
|
||||
void expandJumps();
|
||||
|
||||
void setFunctionTypeInfo(std::string value);
|
||||
|
||||
void setDebugFunctionName(StringRef name);
|
||||
void setDebugFunctionLineDefined(int line);
|
||||
void setDebugLine(int line);
|
||||
void pushDebugLocal(StringRef name, uint8_t reg, uint32_t startpc, uint32_t endpc);
|
||||
void pushDebugUpval(StringRef name);
|
||||
|
||||
size_t getInstructionCount() const;
|
||||
uint32_t getDebugPC() const;
|
||||
|
||||
void addDebugRemark(const char* format, ...) LUAU_PRINTF_ATTR(2, 3);
|
||||
|
||||
void finalize();
|
||||
|
||||
enum DumpFlags
|
||||
{
|
||||
Dump_Code = 1 << 0,
|
||||
Dump_Lines = 1 << 1,
|
||||
Dump_Source = 1 << 2,
|
||||
Dump_Locals = 1 << 3,
|
||||
Dump_Remarks = 1 << 4,
|
||||
};
|
||||
|
||||
void setDumpFlags(uint32_t flags)
|
||||
{
|
||||
dumpFlags = flags;
|
||||
dumpFunctionPtr = &BytecodeBuilder::dumpCurrentFunction;
|
||||
}
|
||||
|
||||
void setDumpSource(const std::string& source);
|
||||
|
||||
bool needsDebugRemarks() const
|
||||
{
|
||||
return (dumpFlags & Dump_Remarks) != 0;
|
||||
}
|
||||
|
||||
const std::string& getBytecode() const
|
||||
{
|
||||
LUAU_ASSERT(!bytecode.empty()); // did you forget to call finalize?
|
||||
return bytecode;
|
||||
}
|
||||
|
||||
std::string dumpFunction(uint32_t id) const;
|
||||
std::string dumpEverything() const;
|
||||
std::string dumpSourceRemarks() const;
|
||||
std::string dumpTypeInfo() const;
|
||||
|
||||
void annotateInstruction(std::string& result, uint32_t fid, uint32_t instpos) const;
|
||||
|
||||
static uint32_t getImportId(int32_t id0);
|
||||
static uint32_t getImportId(int32_t id0, int32_t id1);
|
||||
static uint32_t getImportId(int32_t id0, int32_t id1, int32_t id2);
|
||||
|
||||
static int decomposeImportId(uint32_t ids, int32_t& id0, int32_t& id1, int32_t& id2);
|
||||
|
||||
static uint32_t getStringHash(StringRef key);
|
||||
|
||||
static std::string getError(const std::string& message);
|
||||
|
||||
static uint8_t getVersion();
|
||||
static uint8_t getTypeEncodingVersion();
|
||||
|
||||
private:
|
||||
struct Constant
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Type_Nil,
|
||||
Type_Boolean,
|
||||
Type_Number,
|
||||
Type_String,
|
||||
Type_Import,
|
||||
Type_Table,
|
||||
Type_Closure,
|
||||
};
|
||||
|
||||
Type type;
|
||||
union
|
||||
{
|
||||
bool valueBoolean;
|
||||
double valueNumber;
|
||||
unsigned int valueString; // index into string table
|
||||
uint32_t valueImport; // 10-10-10-2 encoded import id
|
||||
uint32_t valueTable; // index into tableShapes[]
|
||||
uint32_t valueClosure; // index of function in global list
|
||||
};
|
||||
};
|
||||
|
||||
struct ConstantKey
|
||||
{
|
||||
Constant::Type type;
|
||||
// Note: this stores value* from Constant; when type is Number_Double, this stores the same bits as double does but in uint64_t.
|
||||
uint64_t value;
|
||||
|
||||
bool operator==(const ConstantKey& key) const
|
||||
{
|
||||
return type == key.type && value == key.value;
|
||||
}
|
||||
};
|
||||
|
||||
struct Function
|
||||
{
|
||||
std::string data;
|
||||
|
||||
uint8_t maxstacksize = 0;
|
||||
uint8_t numparams = 0;
|
||||
uint8_t numupvalues = 0;
|
||||
bool isvararg = false;
|
||||
|
||||
unsigned int debugname = 0;
|
||||
int debuglinedefined = 0;
|
||||
|
||||
std::string dump;
|
||||
std::string dumpname;
|
||||
std::vector<int> dumpinstoffs;
|
||||
std::string typeinfo;
|
||||
};
|
||||
|
||||
struct DebugLocal
|
||||
{
|
||||
unsigned int name;
|
||||
|
||||
uint8_t reg;
|
||||
uint32_t startpc;
|
||||
uint32_t endpc;
|
||||
};
|
||||
|
||||
struct DebugUpval
|
||||
{
|
||||
unsigned int name;
|
||||
};
|
||||
|
||||
struct Jump
|
||||
{
|
||||
uint32_t source;
|
||||
uint32_t target;
|
||||
};
|
||||
|
||||
struct StringRefHash
|
||||
{
|
||||
size_t operator()(const StringRef& v) const;
|
||||
};
|
||||
|
||||
struct ConstantKeyHash
|
||||
{
|
||||
size_t operator()(const ConstantKey& key) const;
|
||||
};
|
||||
|
||||
struct TableShapeHash
|
||||
{
|
||||
size_t operator()(const TableShape& v) const;
|
||||
};
|
||||
|
||||
std::vector<Function> functions;
|
||||
uint32_t currentFunction = ~0u;
|
||||
uint32_t mainFunction = ~0u;
|
||||
|
||||
std::vector<uint32_t> insns;
|
||||
std::vector<int> lines;
|
||||
std::vector<Constant> constants;
|
||||
std::vector<uint32_t> protos;
|
||||
std::vector<Jump> jumps;
|
||||
|
||||
std::vector<TableShape> tableShapes;
|
||||
|
||||
bool hasLongJumps = false;
|
||||
|
||||
DenseHashMap<ConstantKey, int32_t, ConstantKeyHash> constantMap;
|
||||
DenseHashMap<TableShape, int32_t, TableShapeHash> tableShapeMap;
|
||||
DenseHashMap<uint32_t, int16_t> protoMap;
|
||||
|
||||
int debugLine = 0;
|
||||
|
||||
std::vector<DebugLocal> debugLocals;
|
||||
std::vector<DebugUpval> debugUpvals;
|
||||
|
||||
DenseHashMap<StringRef, unsigned int, StringRefHash> stringTable;
|
||||
std::vector<StringRef> debugStrings;
|
||||
|
||||
std::vector<std::pair<uint32_t, uint32_t>> debugRemarks;
|
||||
std::string debugRemarkBuffer;
|
||||
|
||||
BytecodeEncoder* encoder = nullptr;
|
||||
std::string bytecode;
|
||||
|
||||
uint32_t dumpFlags = 0;
|
||||
std::vector<std::string> dumpSource;
|
||||
std::vector<std::pair<int, std::string>> dumpRemarks;
|
||||
|
||||
std::string (BytecodeBuilder::*dumpFunctionPtr)(std::vector<int>&) const = nullptr;
|
||||
|
||||
void validate() const;
|
||||
void validateInstructions() const;
|
||||
void validateVariadic() const;
|
||||
|
||||
std::string dumpCurrentFunction(std::vector<int>& dumpinstoffs) const;
|
||||
void dumpConstant(std::string& result, int k) const;
|
||||
void dumpInstruction(const uint32_t* opcode, std::string& output, int targetLabel) const;
|
||||
|
||||
void writeFunction(std::string& ss, uint32_t id, uint8_t flags) const;
|
||||
void writeLineInfo(std::string& ss) const;
|
||||
void writeStringTable(std::string& ss) const;
|
||||
|
||||
int32_t addConstant(const ConstantKey& key, const Constant& value);
|
||||
unsigned int addStringTableEntry(StringRef value);
|
||||
};
|
||||
|
||||
} // namespace Luau
|
66
external/luau/include/Luau/CodeAllocator.h
vendored
Normal file
66
external/luau/include/Luau/CodeAllocator.h
vendored
Normal file
|
@ -0,0 +1,66 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/CodeGen.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
constexpr uint32_t kCodeAlignment = 32;
|
||||
|
||||
struct CodeAllocator
|
||||
{
|
||||
CodeAllocator(size_t blockSize, size_t maxTotalSize);
|
||||
CodeAllocator(size_t blockSize, size_t maxTotalSize, AllocationCallback* allocationCallback, void* allocationCallbackContext);
|
||||
~CodeAllocator();
|
||||
|
||||
// Places data and code into the executable page area
|
||||
// To allow allocation while previously allocated code is already running, allocation has page granularity
|
||||
// It's important to group functions together so that page alignment won't result in a lot of wasted space
|
||||
bool allocate(
|
||||
const uint8_t* data, size_t dataSize, const uint8_t* code, size_t codeSize, uint8_t*& result, size_t& resultSize, uint8_t*& resultCodeStart);
|
||||
|
||||
// Provided to unwind info callbacks
|
||||
void* context = nullptr;
|
||||
|
||||
// Called when new block is created to create and setup the unwinding information for all the code in the block
|
||||
// 'startOffset' reserves space for data at the beginning of the page
|
||||
void* (*createBlockUnwindInfo)(void* context, uint8_t* block, size_t blockSize, size_t& startOffset) = nullptr;
|
||||
|
||||
// Called to destroy unwinding information returned by 'createBlockUnwindInfo'
|
||||
void (*destroyBlockUnwindInfo)(void* context, void* unwindData) = nullptr;
|
||||
|
||||
private:
|
||||
// Unwind information can be placed inside the block with some implementation-specific reservations at the beginning
|
||||
// But to simplify block space checks, we limit the max size of all that data
|
||||
static const size_t kMaxReservedDataSize = 256;
|
||||
|
||||
bool allocateNewBlock(size_t& unwindInfoSize);
|
||||
|
||||
uint8_t* allocatePages(size_t size) const;
|
||||
void freePages(uint8_t* mem, size_t size) const;
|
||||
|
||||
// Current block we use for allocations
|
||||
uint8_t* blockPos = nullptr;
|
||||
uint8_t* blockEnd = nullptr;
|
||||
|
||||
// All allocated blocks
|
||||
std::vector<uint8_t*> blocks;
|
||||
std::vector<void*> unwindInfos;
|
||||
|
||||
size_t blockSize = 0;
|
||||
size_t maxTotalSize = 0;
|
||||
|
||||
AllocationCallback* allocationCallback = nullptr;
|
||||
void* allocationCallbackContext = nullptr;
|
||||
};
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
19
external/luau/include/Luau/CodeBlockUnwind.h
vendored
Normal file
19
external/luau/include/Luau/CodeBlockUnwind.h
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
// context must be an UnwindBuilder
|
||||
void* createBlockUnwindInfo(void* context, uint8_t* block, size_t blockSize, size_t& startOffset);
|
||||
void destroyBlockUnwindInfo(void* context, void* unwindData);
|
||||
|
||||
bool isUnwindSupported();
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
85
external/luau/include/Luau/CodeGen.h
vendored
Normal file
85
external/luau/include/Luau/CodeGen.h
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct lua_State;
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
enum CodeGenFlags
|
||||
{
|
||||
// Only run native codegen for modules that have been marked with --!native
|
||||
CodeGen_OnlyNativeModules = 1 << 0,
|
||||
};
|
||||
|
||||
enum class CodeGenCompilationResult
|
||||
{
|
||||
Success, // Successfully generated code for at least one function
|
||||
NothingToCompile, // There were no new functions to compile
|
||||
|
||||
CodeGenNotInitialized, // Native codegen system is not initialized
|
||||
CodeGenFailed, // Native codegen failed due to an internal compiler error
|
||||
AllocationFailed, // Native codegen failed due to an allocation error
|
||||
};
|
||||
|
||||
struct CompilationStats
|
||||
{
|
||||
size_t bytecodeSizeBytes = 0;
|
||||
size_t nativeCodeSizeBytes = 0;
|
||||
size_t nativeDataSizeBytes = 0;
|
||||
size_t nativeMetadataSizeBytes = 0;
|
||||
|
||||
uint32_t functionsCompiled = 0;
|
||||
};
|
||||
|
||||
using AllocationCallback = void(void* context, void* oldPointer, size_t oldSize, void* newPointer, size_t newSize);
|
||||
|
||||
bool isSupported();
|
||||
|
||||
void create(lua_State* L, AllocationCallback* allocationCallback, void* allocationCallbackContext);
|
||||
void create(lua_State* L);
|
||||
|
||||
// Builds target function and all inner functions
|
||||
CodeGenCompilationResult compile(lua_State* L, int idx, unsigned int flags = 0, CompilationStats* stats = nullptr);
|
||||
|
||||
using AnnotatorFn = void (*)(void* context, std::string& result, int fid, int instpos);
|
||||
|
||||
struct AssemblyOptions
|
||||
{
|
||||
enum Target
|
||||
{
|
||||
Host,
|
||||
A64,
|
||||
A64_NoFeatures,
|
||||
X64_Windows,
|
||||
X64_SystemV,
|
||||
};
|
||||
|
||||
Target target = Host;
|
||||
|
||||
bool outputBinary = false;
|
||||
|
||||
bool includeAssembly = false;
|
||||
bool includeIr = false;
|
||||
bool includeOutlinedCode = false;
|
||||
|
||||
// Optional annotator function can be provided to describe each instruction, it takes function id and sequential instruction id
|
||||
AnnotatorFn annotator = nullptr;
|
||||
void* annotatorContext = nullptr;
|
||||
};
|
||||
|
||||
// Generates assembly for target function and all inner functions
|
||||
std::string getAssembly(lua_State* L, int idx, AssemblyOptions options = {});
|
||||
|
||||
using PerfLogFn = void (*)(void* context, uintptr_t addr, unsigned size, const char* symbol);
|
||||
|
||||
void setPerfLog(void* context, PerfLogFn logFn);
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
71
external/luau/include/Luau/Compiler.h
vendored
Normal file
71
external/luau/include/Luau/Compiler.h
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/ParseOptions.h"
|
||||
#include "Luau/Location.h"
|
||||
#include "Luau/StringUtils.h"
|
||||
#include "Luau/Common.h"
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
class AstNameTable;
|
||||
struct ParseResult;
|
||||
class BytecodeBuilder;
|
||||
class BytecodeEncoder;
|
||||
|
||||
// Note: this structure is duplicated in luacode.h, don't forget to change these in sync!
|
||||
struct CompileOptions
|
||||
{
|
||||
// 0 - no optimization
|
||||
// 1 - baseline optimization level that doesn't prevent debuggability
|
||||
// 2 - includes optimizations that harm debuggability such as inlining
|
||||
int optimizationLevel = 1;
|
||||
|
||||
// 0 - no debugging support
|
||||
// 1 - line info & function names only; sufficient for backtraces
|
||||
// 2 - full debug info with local & upvalue names; necessary for debugger
|
||||
int debugLevel = 1;
|
||||
|
||||
// 0 - no code coverage support
|
||||
// 1 - statement coverage
|
||||
// 2 - statement and expression coverage (verbose)
|
||||
int coverageLevel = 0;
|
||||
|
||||
// global builtin to construct vectors; disabled by default
|
||||
const char* vectorLib = nullptr;
|
||||
const char* vectorCtor = nullptr;
|
||||
|
||||
// vector type name for type tables; disabled by default
|
||||
const char* vectorType = nullptr;
|
||||
|
||||
// null-terminated array of globals that are mutable; disables the import optimization for fields accessed through these
|
||||
const char* const* mutableGlobals = nullptr;
|
||||
};
|
||||
|
||||
class CompileError : public std::exception
|
||||
{
|
||||
public:
|
||||
CompileError(const Location& location, const std::string& message);
|
||||
|
||||
virtual ~CompileError() throw();
|
||||
|
||||
virtual const char* what() const throw();
|
||||
|
||||
const Location& getLocation() const;
|
||||
|
||||
static LUAU_NORETURN void raise(const Location& location, const char* format, ...) LUAU_PRINTF_ATTR(2, 3);
|
||||
|
||||
private:
|
||||
Location location;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
// compiles bytecode into bytecode builder using either a pre-parsed AST or parsing it from source; throws on errors
|
||||
void compileOrThrow(BytecodeBuilder& bytecode, const ParseResult& parseResult, const AstNameTable& names, const CompileOptions& options = {});
|
||||
void compileOrThrow(BytecodeBuilder& bytecode, const std::string& source, const CompileOptions& options = {}, const ParseOptions& parseOptions = {});
|
||||
|
||||
// compiles bytecode into a bytecode blob, that either contains the valid bytecode or an encoded error that luau_load can decode
|
||||
std::string compile(
|
||||
const std::string& source, const CompileOptions& options = {}, const ParseOptions& parseOptions = {}, BytecodeEncoder* encoder = nullptr);
|
||||
|
||||
} // namespace Luau
|
57
external/luau/include/Luau/ConditionA64.h
vendored
Normal file
57
external/luau/include/Luau/ConditionA64.h
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace A64
|
||||
{
|
||||
|
||||
// See Table C1-1 on page C1-229 of Arm ARM for A-profile architecture
|
||||
enum class ConditionA64
|
||||
{
|
||||
// EQ: integer (equal), floating-point (equal)
|
||||
Equal,
|
||||
// NE: integer (not equal), floating-point (not equal or unordered)
|
||||
NotEqual,
|
||||
|
||||
// CS: integer (carry set), unsigned integer (greater than, equal), floating-point (greater than, equal or unordered)
|
||||
CarrySet,
|
||||
// CC: integer (carry clear), unsigned integer (less than), floating-point (less than)
|
||||
CarryClear,
|
||||
|
||||
// MI: integer (negative), floating-point (less than)
|
||||
Minus,
|
||||
// PL: integer (positive or zero), floating-point (greater than, equal or unordered)
|
||||
Plus,
|
||||
|
||||
// VS: integer (overflow), floating-point (unordered)
|
||||
Overflow,
|
||||
// VC: integer (no overflow), floating-point (ordered)
|
||||
NoOverflow,
|
||||
|
||||
// HI: integer (unsigned higher), floating-point (greater than, or unordered)
|
||||
UnsignedGreater,
|
||||
// LS: integer (unsigned lower or same), floating-point (less than or equal)
|
||||
UnsignedLessEqual,
|
||||
|
||||
// GE: integer (signed greater than or equal), floating-point (greater than or equal)
|
||||
GreaterEqual,
|
||||
// LT: integer (signed less than), floating-point (less than, or unordered)
|
||||
Less,
|
||||
|
||||
// GT: integer (signed greater than), floating-point (greater than)
|
||||
Greater,
|
||||
// LE: integer (signed less than or equal), floating-point (less than, equal or unordered)
|
||||
LessEqual,
|
||||
|
||||
// AL: always
|
||||
Always,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
} // namespace A64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
112
external/luau/include/Luau/ConditionX64.h
vendored
Normal file
112
external/luau/include/Luau/ConditionX64.h
vendored
Normal file
|
@ -0,0 +1,112 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
enum class ConditionX64 : uint8_t
|
||||
{
|
||||
Overflow,
|
||||
NoOverflow,
|
||||
|
||||
Carry,
|
||||
NoCarry,
|
||||
|
||||
Below,
|
||||
BelowEqual,
|
||||
Above,
|
||||
AboveEqual,
|
||||
Equal,
|
||||
Less,
|
||||
LessEqual,
|
||||
Greater,
|
||||
GreaterEqual,
|
||||
|
||||
NotBelow,
|
||||
NotBelowEqual,
|
||||
NotAbove,
|
||||
NotAboveEqual,
|
||||
NotEqual,
|
||||
NotLess,
|
||||
NotLessEqual,
|
||||
NotGreater,
|
||||
NotGreaterEqual,
|
||||
|
||||
Zero,
|
||||
NotZero,
|
||||
|
||||
Parity,
|
||||
NotParity,
|
||||
|
||||
Count
|
||||
};
|
||||
|
||||
inline ConditionX64 getReverseCondition(ConditionX64 cond)
|
||||
{
|
||||
switch (cond)
|
||||
{
|
||||
case ConditionX64::Overflow:
|
||||
return ConditionX64::NoOverflow;
|
||||
case ConditionX64::NoOverflow:
|
||||
return ConditionX64::Overflow;
|
||||
case ConditionX64::Carry:
|
||||
return ConditionX64::NoCarry;
|
||||
case ConditionX64::NoCarry:
|
||||
return ConditionX64::Carry;
|
||||
case ConditionX64::Below:
|
||||
return ConditionX64::NotBelow;
|
||||
case ConditionX64::BelowEqual:
|
||||
return ConditionX64::NotBelowEqual;
|
||||
case ConditionX64::Above:
|
||||
return ConditionX64::NotAbove;
|
||||
case ConditionX64::AboveEqual:
|
||||
return ConditionX64::NotAboveEqual;
|
||||
case ConditionX64::Equal:
|
||||
return ConditionX64::NotEqual;
|
||||
case ConditionX64::Less:
|
||||
return ConditionX64::NotLess;
|
||||
case ConditionX64::LessEqual:
|
||||
return ConditionX64::NotLessEqual;
|
||||
case ConditionX64::Greater:
|
||||
return ConditionX64::NotGreater;
|
||||
case ConditionX64::GreaterEqual:
|
||||
return ConditionX64::NotGreaterEqual;
|
||||
case ConditionX64::NotBelow:
|
||||
return ConditionX64::Below;
|
||||
case ConditionX64::NotBelowEqual:
|
||||
return ConditionX64::BelowEqual;
|
||||
case ConditionX64::NotAbove:
|
||||
return ConditionX64::Above;
|
||||
case ConditionX64::NotAboveEqual:
|
||||
return ConditionX64::AboveEqual;
|
||||
case ConditionX64::NotEqual:
|
||||
return ConditionX64::Equal;
|
||||
case ConditionX64::NotLess:
|
||||
return ConditionX64::Less;
|
||||
case ConditionX64::NotLessEqual:
|
||||
return ConditionX64::LessEqual;
|
||||
case ConditionX64::NotGreater:
|
||||
return ConditionX64::Greater;
|
||||
case ConditionX64::NotGreaterEqual:
|
||||
return ConditionX64::GreaterEqual;
|
||||
case ConditionX64::Zero:
|
||||
return ConditionX64::NotZero;
|
||||
case ConditionX64::NotZero:
|
||||
return ConditionX64::Zero;
|
||||
case ConditionX64::Parity:
|
||||
return ConditionX64::NotParity;
|
||||
case ConditionX64::NotParity:
|
||||
return ConditionX64::Parity;
|
||||
case ConditionX64::Count:
|
||||
LUAU_ASSERT(!"invalid ConditionX64 value");
|
||||
}
|
||||
|
||||
return ConditionX64::Count;
|
||||
}
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
55
external/luau/include/Luau/Config.h
vendored
Normal file
55
external/luau/include/Luau/Config.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/LinterConfig.h"
|
||||
#include "Luau/ParseOptions.h"
|
||||
|
||||
#include <string>
|
||||
#include <optional>
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
using ModuleName = std::string;
|
||||
|
||||
constexpr const char* kConfigName = ".luaurc";
|
||||
|
||||
struct Config
|
||||
{
|
||||
Config();
|
||||
|
||||
Mode mode = Mode::Nonstrict;
|
||||
|
||||
ParseOptions parseOptions;
|
||||
|
||||
LintOptions enabledLint;
|
||||
LintOptions fatalLint;
|
||||
|
||||
bool lintErrors = false;
|
||||
bool typeErrors = true;
|
||||
|
||||
std::vector<std::string> globals;
|
||||
};
|
||||
|
||||
struct ConfigResolver
|
||||
{
|
||||
virtual ~ConfigResolver() {}
|
||||
|
||||
virtual const Config& getConfig(const ModuleName& name) const = 0;
|
||||
};
|
||||
|
||||
struct NullConfigResolver : ConfigResolver
|
||||
{
|
||||
Config defaultConfig;
|
||||
|
||||
virtual const Config& getConfig(const ModuleName& name) const override;
|
||||
};
|
||||
|
||||
std::optional<std::string> parseModeString(Mode& mode, const std::string& modeString, bool compat = false);
|
||||
std::optional<std::string> parseLintRuleString(
|
||||
LintOptions& enabledLints, LintOptions& fatalLints, const std::string& warningName, const std::string& value, bool compat = false);
|
||||
|
||||
std::optional<std::string> parseConfig(const std::string& contents, Config& config, bool compat = false);
|
||||
|
||||
} // namespace Luau
|
9
external/luau/include/Luau/Confusables.h
vendored
Normal file
9
external/luau/include/Luau/Confusables.h
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
const char* findConfusable(uint32_t codepoint);
|
||||
}
|
180
external/luau/include/Luau/IrAnalysis.h
vendored
Normal file
180
external/luau/include/Luau/IrAnalysis.h
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <bitset>
|
||||
#include <queue>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct IrBlock;
|
||||
struct IrFunction;
|
||||
|
||||
void updateUseCounts(IrFunction& function);
|
||||
|
||||
void updateLastUseLocations(IrFunction& function);
|
||||
|
||||
uint32_t getNextInstUse(IrFunction& function, uint32_t targetInstIdx, uint32_t startInstIdx);
|
||||
|
||||
// Returns how many values are coming into the block (live in) and how many are coming out of the block (live out)
|
||||
std::pair<uint32_t, uint32_t> getLiveInOutValueCount(IrFunction& function, IrBlock& block);
|
||||
uint32_t getLiveInValueCount(IrFunction& function, IrBlock& block);
|
||||
uint32_t getLiveOutValueCount(IrFunction& function, IrBlock& block);
|
||||
|
||||
struct RegisterSet
|
||||
{
|
||||
std::bitset<256> regs;
|
||||
|
||||
// If variadic sequence is active, we track register from which it starts
|
||||
bool varargSeq = false;
|
||||
uint8_t varargStart = 0;
|
||||
};
|
||||
|
||||
void requireVariadicSequence(RegisterSet& sourceRs, const RegisterSet& defRs, uint8_t varargStart);
|
||||
|
||||
struct BlockOrdering
|
||||
{
|
||||
uint32_t depth = 0;
|
||||
|
||||
uint32_t preOrder = ~0u;
|
||||
uint32_t postOrder = ~0u;
|
||||
|
||||
bool visited = false;
|
||||
};
|
||||
|
||||
struct CfgInfo
|
||||
{
|
||||
std::vector<uint32_t> predecessors;
|
||||
std::vector<uint32_t> predecessorsOffsets;
|
||||
|
||||
std::vector<uint32_t> successors;
|
||||
std::vector<uint32_t> successorsOffsets;
|
||||
|
||||
// Immediate dominators (unique parent in the dominator tree)
|
||||
std::vector<uint32_t> idoms;
|
||||
|
||||
// Children in the dominator tree
|
||||
std::vector<uint32_t> domChildren;
|
||||
std::vector<uint32_t> domChildrenOffsets;
|
||||
|
||||
std::vector<BlockOrdering> domOrdering;
|
||||
|
||||
// VM registers that are live when the block is entered
|
||||
// Additionally, an active variadic sequence can exist at the entry of the block
|
||||
std::vector<RegisterSet> in;
|
||||
|
||||
// VM registers that are defined inside the block
|
||||
// It can also contain a variadic sequence definition if that hasn't been consumed inside the block
|
||||
// Note that this means that checking 'def' set might not be enough to say that register has not been written to
|
||||
std::vector<RegisterSet> def;
|
||||
|
||||
// VM registers that are coming out from the block
|
||||
// These might be registers that are defined inside the block or have been defined at the entry of the block
|
||||
// Additionally, an active variadic sequence can exist at the exit of the block
|
||||
std::vector<RegisterSet> out;
|
||||
|
||||
// VM registers captured by nested closures
|
||||
// This set can never have an active variadic sequence
|
||||
RegisterSet captured;
|
||||
};
|
||||
|
||||
// A quick refresher on dominance and dominator trees:
|
||||
// * If A is a dominator of B (A dom B), you can never execute B without executing A first
|
||||
// * A is a strict dominator of B (A sdom B) is similar to previous one but A != B
|
||||
// * Immediate dominator node N (idom N) is a unique node T so that T sdom N,
|
||||
// but T does not strictly dominate any other node that dominates N.
|
||||
// * Dominance frontier is a set of nodes where dominance of a node X ends.
|
||||
// In practice this is where values established by node X might no longer hold because of join edges from other nodes coming in.
|
||||
// This is also where PHI instructions in SSA are placed.
|
||||
void computeCfgImmediateDominators(IrFunction& function);
|
||||
void computeCfgDominanceTreeChildren(IrFunction& function);
|
||||
|
||||
struct IdfContext
|
||||
{
|
||||
struct BlockAndOrdering
|
||||
{
|
||||
uint32_t blockIdx;
|
||||
BlockOrdering ordering;
|
||||
|
||||
bool operator<(const BlockAndOrdering& rhs) const
|
||||
{
|
||||
if (ordering.depth != rhs.ordering.depth)
|
||||
return ordering.depth < rhs.ordering.depth;
|
||||
|
||||
return ordering.preOrder < rhs.ordering.preOrder;
|
||||
}
|
||||
};
|
||||
|
||||
// Using priority queue to work on nodes in the order from the bottom of the dominator tree to the top
|
||||
// If the depth of keys is equal, DFS order is used to provide strong ordering
|
||||
std::priority_queue<BlockAndOrdering> queue;
|
||||
std::vector<uint32_t> worklist;
|
||||
|
||||
struct IdfVisitMarks
|
||||
{
|
||||
bool seenInQueue = false;
|
||||
bool seenInWorklist = false;
|
||||
};
|
||||
|
||||
std::vector<IdfVisitMarks> visits;
|
||||
|
||||
std::vector<uint32_t> idf;
|
||||
};
|
||||
|
||||
// Compute iterated dominance frontier (IDF or DF+) for a variable, given the set of blocks where that variable is defined
|
||||
// Providing a set of blocks where the variable is a live-in at the entry helps produce a pruned SSA form (inserted phi nodes will not be dead)
|
||||
//
|
||||
// 'Iterated' comes from the definition where we recompute the IDFn+1 = DF(S) while adding IDFn to S until a fixed point is reached
|
||||
// Iterated dominance frontier has been shown to be equal to the set of nodes where phi instructions have to be inserted
|
||||
void computeIteratedDominanceFrontierForDefs(
|
||||
IdfContext& ctx, const IrFunction& function, const std::vector<uint32_t>& defBlocks, const std::vector<uint32_t>& liveInBlocks);
|
||||
|
||||
// Function used to update all CFG data
|
||||
void computeCfgInfo(IrFunction& function);
|
||||
|
||||
struct BlockIteratorWrapper
|
||||
{
|
||||
const uint32_t* itBegin = nullptr;
|
||||
const uint32_t* itEnd = nullptr;
|
||||
|
||||
bool empty() const
|
||||
{
|
||||
return itBegin == itEnd;
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return size_t(itEnd - itBegin);
|
||||
}
|
||||
|
||||
const uint32_t* begin() const
|
||||
{
|
||||
return itBegin;
|
||||
}
|
||||
|
||||
const uint32_t* end() const
|
||||
{
|
||||
return itEnd;
|
||||
}
|
||||
|
||||
uint32_t operator[](size_t pos) const
|
||||
{
|
||||
LUAU_ASSERT(pos < size_t(itEnd - itBegin));
|
||||
return itBegin[pos];
|
||||
}
|
||||
};
|
||||
|
||||
BlockIteratorWrapper predecessors(const CfgInfo& cfg, uint32_t blockIdx);
|
||||
BlockIteratorWrapper successors(const CfgInfo& cfg, uint32_t blockIdx);
|
||||
BlockIteratorWrapper domChildren(const CfgInfo& cfg, uint32_t blockIdx);
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
120
external/luau/include/Luau/IrBuilder.h
vendored
Normal file
120
external/luau/include/Luau/IrBuilder.h
vendored
Normal file
|
@ -0,0 +1,120 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Bytecode.h"
|
||||
#include "Luau/Common.h"
|
||||
#include "Luau/DenseHash.h"
|
||||
#include "Luau/IrData.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
struct Proto;
|
||||
typedef uint32_t Instruction;
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct AssemblyOptions;
|
||||
|
||||
struct IrBuilder
|
||||
{
|
||||
IrBuilder();
|
||||
|
||||
void buildFunctionIr(Proto* proto);
|
||||
|
||||
void rebuildBytecodeBasicBlocks(Proto* proto);
|
||||
void translateInst(LuauOpcode op, const Instruction* pc, int i);
|
||||
void handleFastcallFallback(IrOp fallbackOrUndef, const Instruction* pc, int i);
|
||||
|
||||
bool isInternalBlock(IrOp block);
|
||||
void beginBlock(IrOp block);
|
||||
|
||||
void loadAndCheckTag(IrOp loc, uint8_t tag, IrOp fallback);
|
||||
|
||||
// Clones all instructions into the current block
|
||||
// Source block that is cloned cannot use values coming in from a predecessor
|
||||
void clone(const IrBlock& source, bool removeCurrentTerminator);
|
||||
|
||||
IrOp undef();
|
||||
|
||||
IrOp constInt(int value);
|
||||
IrOp constUint(unsigned value);
|
||||
IrOp constDouble(double value);
|
||||
IrOp constTag(uint8_t value);
|
||||
IrOp constAny(IrConst constant, uint64_t asCommonKey);
|
||||
|
||||
IrOp cond(IrCondition cond);
|
||||
|
||||
IrOp inst(IrCmd cmd);
|
||||
IrOp inst(IrCmd cmd, IrOp a);
|
||||
IrOp inst(IrCmd cmd, IrOp a, IrOp b);
|
||||
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c);
|
||||
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d);
|
||||
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d, IrOp e);
|
||||
IrOp inst(IrCmd cmd, IrOp a, IrOp b, IrOp c, IrOp d, IrOp e, IrOp f);
|
||||
|
||||
IrOp block(IrBlockKind kind); // Requested kind can be ignored if we are in an outlined sequence
|
||||
IrOp blockAtInst(uint32_t index);
|
||||
|
||||
IrOp vmReg(uint8_t index);
|
||||
IrOp vmConst(uint32_t index);
|
||||
IrOp vmUpvalue(uint8_t index);
|
||||
|
||||
IrOp vmExit(uint32_t pcpos);
|
||||
|
||||
bool inTerminatedBlock = false;
|
||||
|
||||
bool activeFastcallFallback = false;
|
||||
IrOp fastcallFallbackReturn;
|
||||
int fastcallSkipTarget = -1;
|
||||
|
||||
IrFunction function;
|
||||
|
||||
uint32_t activeBlockIdx = ~0u;
|
||||
|
||||
std::vector<uint32_t> instIndexToBlock; // Block index at the bytecode instruction
|
||||
|
||||
// Similar to BytecodeBuilder, duplicate constants are removed used the same method
|
||||
struct ConstantKey
|
||||
{
|
||||
IrConstKind kind;
|
||||
// Note: this stores value* from IrConst; when kind is Double, this stores the same bits as double does but in uint64_t.
|
||||
uint64_t value;
|
||||
|
||||
bool operator==(const ConstantKey& key) const
|
||||
{
|
||||
return kind == key.kind && value == key.value;
|
||||
}
|
||||
};
|
||||
|
||||
struct ConstantKeyHash
|
||||
{
|
||||
size_t operator()(const ConstantKey& key) const
|
||||
{
|
||||
// finalizer from MurmurHash64B
|
||||
const uint32_t m = 0x5bd1e995;
|
||||
|
||||
uint32_t h1 = uint32_t(key.value);
|
||||
uint32_t h2 = uint32_t(key.value >> 32) ^ (int(key.kind) * m);
|
||||
|
||||
h1 ^= h2 >> 18;
|
||||
h1 *= m;
|
||||
h2 ^= h1 >> 22;
|
||||
h2 *= m;
|
||||
h1 ^= h2 >> 17;
|
||||
h1 *= m;
|
||||
h2 ^= h1 >> 19;
|
||||
h2 *= m;
|
||||
|
||||
// ... truncated to 32-bit output (normally hash is equal to (uint64_t(h1) << 32) | h2, but we only really need the lower 32-bit half)
|
||||
return size_t(h2);
|
||||
}
|
||||
};
|
||||
|
||||
DenseHashMap<ConstantKey, uint32_t, ConstantKeyHash> constantMap;
|
||||
};
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
84
external/luau/include/Luau/IrCallWrapperX64.h
vendored
Normal file
84
external/luau/include/Luau/IrCallWrapperX64.h
vendored
Normal file
|
@ -0,0 +1,84 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/AssemblyBuilderX64.h"
|
||||
#include "Luau/IrData.h"
|
||||
#include "Luau/OperandX64.h"
|
||||
#include "Luau/RegisterX64.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
// TODO: call wrapper can be used to suggest target registers for ScopedRegX64 to compute data into argument registers directly
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace X64
|
||||
{
|
||||
|
||||
struct IrRegAllocX64;
|
||||
struct ScopedRegX64;
|
||||
|
||||
struct CallArgument
|
||||
{
|
||||
SizeX64 targetSize = SizeX64::none;
|
||||
|
||||
OperandX64 source = noreg;
|
||||
IrOp sourceOp;
|
||||
|
||||
OperandX64 target = noreg;
|
||||
bool candidate = true;
|
||||
};
|
||||
|
||||
class IrCallWrapperX64
|
||||
{
|
||||
public:
|
||||
IrCallWrapperX64(IrRegAllocX64& regs, AssemblyBuilderX64& build, uint32_t instIdx = kInvalidInstIdx);
|
||||
|
||||
void addArgument(SizeX64 targetSize, OperandX64 source, IrOp sourceOp = {});
|
||||
void addArgument(SizeX64 targetSize, ScopedRegX64& scopedReg);
|
||||
|
||||
void call(const OperandX64& func);
|
||||
|
||||
RegisterX64 suggestNextArgumentRegister(SizeX64 size) const;
|
||||
|
||||
IrRegAllocX64& regs;
|
||||
AssemblyBuilderX64& build;
|
||||
uint32_t instIdx = ~0u;
|
||||
|
||||
private:
|
||||
OperandX64 getNextArgumentTarget(SizeX64 size) const;
|
||||
void countRegisterUses();
|
||||
CallArgument* findNonInterferingArgument();
|
||||
bool interferesWithOperand(const OperandX64& op, RegisterX64 reg) const;
|
||||
bool interferesWithActiveSources(const CallArgument& targetArg, int targetArgIndex) const;
|
||||
bool interferesWithActiveTarget(RegisterX64 sourceReg) const;
|
||||
void moveToTarget(CallArgument& arg);
|
||||
void freeSourceRegisters(CallArgument& arg);
|
||||
void renameRegister(RegisterX64& target, RegisterX64 reg, RegisterX64 replacement);
|
||||
void renameSourceRegisters(RegisterX64 reg, RegisterX64 replacement);
|
||||
RegisterX64 findConflictingTarget() const;
|
||||
void renameConflictingRegister(RegisterX64 conflict);
|
||||
|
||||
int getRegisterUses(RegisterX64 reg) const;
|
||||
void addRegisterUse(RegisterX64 reg);
|
||||
void removeRegisterUse(RegisterX64 reg);
|
||||
|
||||
static const int kMaxCallArguments = 6;
|
||||
std::array<CallArgument, kMaxCallArguments> args;
|
||||
int argCount = 0;
|
||||
|
||||
int gprPos = 0;
|
||||
int xmmPos = 0;
|
||||
|
||||
OperandX64 funcOp;
|
||||
|
||||
// Internal counters for remaining register use counts
|
||||
std::array<uint8_t, 16> gprUses;
|
||||
std::array<uint8_t, 16> xmmUses;
|
||||
};
|
||||
|
||||
} // namespace X64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
1065
external/luau/include/Luau/IrData.h
vendored
Normal file
1065
external/luau/include/Luau/IrData.h
vendored
Normal file
File diff suppressed because it is too large
Load diff
47
external/luau/include/Luau/IrDump.h
vendored
Normal file
47
external/luau/include/Luau/IrDump.h
vendored
Normal file
|
@ -0,0 +1,47 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/IrData.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct CfgInfo;
|
||||
|
||||
const char* getCmdName(IrCmd cmd);
|
||||
const char* getBlockKindName(IrBlockKind kind);
|
||||
|
||||
struct IrToStringContext
|
||||
{
|
||||
std::string& result;
|
||||
const std::vector<IrBlock>& blocks;
|
||||
const std::vector<IrConst>& constants;
|
||||
const CfgInfo& cfg;
|
||||
};
|
||||
|
||||
void toString(IrToStringContext& ctx, const IrInst& inst, uint32_t index);
|
||||
void toString(IrToStringContext& ctx, const IrBlock& block, uint32_t index); // Block title
|
||||
void toString(IrToStringContext& ctx, IrOp op);
|
||||
|
||||
void toString(std::string& result, IrConst constant);
|
||||
|
||||
void toStringDetailed(IrToStringContext& ctx, const IrBlock& block, uint32_t blockIdx, const IrInst& inst, uint32_t instIdx, bool includeUseInfo);
|
||||
void toStringDetailed(IrToStringContext& ctx, const IrBlock& block, uint32_t index, bool includeUseInfo); // Block title
|
||||
|
||||
std::string toString(const IrFunction& function, bool includeUseInfo);
|
||||
|
||||
std::string dump(const IrFunction& function);
|
||||
|
||||
std::string toDot(const IrFunction& function, bool includeInst);
|
||||
std::string toDotCfg(const IrFunction& function);
|
||||
std::string toDotDjGraph(const IrFunction& function);
|
||||
|
||||
std::string dumpDot(const IrFunction& function, bool includeInst);
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
124
external/luau/include/Luau/IrRegAllocX64.h
vendored
Normal file
124
external/luau/include/Luau/IrRegAllocX64.h
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/AssemblyBuilderX64.h"
|
||||
#include "Luau/IrData.h"
|
||||
#include "Luau/RegisterX64.h"
|
||||
|
||||
#include <array>
|
||||
#include <initializer_list>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace X64
|
||||
{
|
||||
|
||||
constexpr uint8_t kNoStackSlot = 0xff;
|
||||
|
||||
struct IrSpillX64
|
||||
{
|
||||
uint32_t instIdx = 0;
|
||||
IrValueKind valueKind = IrValueKind::Unknown;
|
||||
|
||||
unsigned spillId = 0;
|
||||
|
||||
// Spill location can be a stack location or be empty
|
||||
// When it's empty, it means that instruction value can be rematerialized
|
||||
uint8_t stackSlot = kNoStackSlot;
|
||||
|
||||
RegisterX64 originalLoc = noreg;
|
||||
};
|
||||
|
||||
struct IrRegAllocX64
|
||||
{
|
||||
IrRegAllocX64(AssemblyBuilderX64& build, IrFunction& function);
|
||||
|
||||
RegisterX64 allocReg(SizeX64 size, uint32_t instIdx);
|
||||
RegisterX64 allocRegOrReuse(SizeX64 size, uint32_t instIdx, std::initializer_list<IrOp> oprefs);
|
||||
RegisterX64 takeReg(RegisterX64 reg, uint32_t instIdx);
|
||||
|
||||
bool canTakeReg(RegisterX64 reg) const;
|
||||
|
||||
void freeReg(RegisterX64 reg);
|
||||
void freeLastUseReg(IrInst& target, uint32_t instIdx);
|
||||
void freeLastUseRegs(const IrInst& inst, uint32_t instIdx);
|
||||
|
||||
bool isLastUseReg(const IrInst& target, uint32_t instIdx) const;
|
||||
|
||||
bool shouldFreeGpr(RegisterX64 reg) const;
|
||||
|
||||
unsigned findSpillStackSlot(IrValueKind valueKind);
|
||||
|
||||
IrOp getRestoreOp(const IrInst& inst) const;
|
||||
bool hasRestoreOp(const IrInst& inst) const;
|
||||
OperandX64 getRestoreAddress(const IrInst& inst, IrOp restoreOp);
|
||||
|
||||
// Register used by instruction is about to be freed, have to find a way to restore value later
|
||||
void preserve(IrInst& inst);
|
||||
|
||||
void restore(IrInst& inst, bool intoOriginalLocation);
|
||||
|
||||
void preserveAndFreeInstValues();
|
||||
|
||||
uint32_t findInstructionWithFurthestNextUse(const std::array<uint32_t, 16>& regInstUsers) const;
|
||||
|
||||
void assertFree(RegisterX64 reg) const;
|
||||
void assertAllFree() const;
|
||||
void assertNoSpills() const;
|
||||
|
||||
AssemblyBuilderX64& build;
|
||||
IrFunction& function;
|
||||
|
||||
uint32_t currInstIdx = ~0u;
|
||||
|
||||
std::array<bool, 16> freeGprMap;
|
||||
std::array<uint32_t, 16> gprInstUsers;
|
||||
std::array<bool, 16> freeXmmMap;
|
||||
std::array<uint32_t, 16> xmmInstUsers;
|
||||
uint8_t usableXmmRegCount = 0;
|
||||
|
||||
std::bitset<256> usedSpillSlots;
|
||||
unsigned maxUsedSlot = 0;
|
||||
unsigned nextSpillId = 1;
|
||||
std::vector<IrSpillX64> spills;
|
||||
};
|
||||
|
||||
struct ScopedRegX64
|
||||
{
|
||||
explicit ScopedRegX64(IrRegAllocX64& owner);
|
||||
ScopedRegX64(IrRegAllocX64& owner, SizeX64 size);
|
||||
ScopedRegX64(IrRegAllocX64& owner, RegisterX64 reg);
|
||||
~ScopedRegX64();
|
||||
|
||||
ScopedRegX64(const ScopedRegX64&) = delete;
|
||||
ScopedRegX64& operator=(const ScopedRegX64&) = delete;
|
||||
|
||||
void alloc(SizeX64 size);
|
||||
void free();
|
||||
|
||||
RegisterX64 release();
|
||||
|
||||
IrRegAllocX64& owner;
|
||||
RegisterX64 reg;
|
||||
};
|
||||
|
||||
// When IR instruction makes a call under a condition that's not reflected as a real branch in IR,
|
||||
// spilled values have to be restored to their exact original locations, so that both after a call
|
||||
// and after the skip, values are found in the same place
|
||||
struct ScopedSpills
|
||||
{
|
||||
explicit ScopedSpills(IrRegAllocX64& owner);
|
||||
~ScopedSpills();
|
||||
|
||||
ScopedSpills(const ScopedSpills&) = delete;
|
||||
ScopedSpills& operator=(const ScopedSpills&) = delete;
|
||||
|
||||
IrRegAllocX64& owner;
|
||||
unsigned startSpillId = 0;
|
||||
};
|
||||
|
||||
} // namespace X64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
270
external/luau/include/Luau/IrUtils.h
vendored
Normal file
270
external/luau/include/Luau/IrUtils.h
vendored
Normal file
|
@ -0,0 +1,270 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Bytecode.h"
|
||||
#include "Luau/Common.h"
|
||||
#include "Luau/IrData.h"
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct IrBuilder;
|
||||
|
||||
inline bool isJumpD(LuauOpcode op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case LOP_JUMP:
|
||||
case LOP_JUMPIF:
|
||||
case LOP_JUMPIFNOT:
|
||||
case LOP_JUMPIFEQ:
|
||||
case LOP_JUMPIFLE:
|
||||
case LOP_JUMPIFLT:
|
||||
case LOP_JUMPIFNOTEQ:
|
||||
case LOP_JUMPIFNOTLE:
|
||||
case LOP_JUMPIFNOTLT:
|
||||
case LOP_FORNPREP:
|
||||
case LOP_FORNLOOP:
|
||||
case LOP_FORGPREP:
|
||||
case LOP_FORGLOOP:
|
||||
case LOP_FORGPREP_INEXT:
|
||||
case LOP_FORGPREP_NEXT:
|
||||
case LOP_JUMPBACK:
|
||||
case LOP_JUMPXEQKNIL:
|
||||
case LOP_JUMPXEQKB:
|
||||
case LOP_JUMPXEQKN:
|
||||
case LOP_JUMPXEQKS:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isSkipC(LuauOpcode op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case LOP_LOADB:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline bool isFastCall(LuauOpcode op)
|
||||
{
|
||||
switch (op)
|
||||
{
|
||||
case LOP_FASTCALL:
|
||||
case LOP_FASTCALL1:
|
||||
case LOP_FASTCALL2:
|
||||
case LOP_FASTCALL2K:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
inline int getJumpTarget(uint32_t insn, uint32_t pc)
|
||||
{
|
||||
LuauOpcode op = LuauOpcode(LUAU_INSN_OP(insn));
|
||||
|
||||
if (isJumpD(op))
|
||||
return int(pc + LUAU_INSN_D(insn) + 1);
|
||||
else if (isFastCall(op))
|
||||
return int(pc + LUAU_INSN_C(insn) + 2);
|
||||
else if (isSkipC(op) && LUAU_INSN_C(insn))
|
||||
return int(pc + LUAU_INSN_C(insn) + 1);
|
||||
else if (op == LOP_JUMPX)
|
||||
return int(pc + LUAU_INSN_E(insn) + 1);
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
inline bool isBlockTerminator(IrCmd cmd)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case IrCmd::JUMP:
|
||||
case IrCmd::JUMP_IF_TRUTHY:
|
||||
case IrCmd::JUMP_IF_FALSY:
|
||||
case IrCmd::JUMP_EQ_TAG:
|
||||
case IrCmd::JUMP_EQ_INT:
|
||||
case IrCmd::JUMP_LT_INT:
|
||||
case IrCmd::JUMP_GE_UINT:
|
||||
case IrCmd::JUMP_EQ_POINTER:
|
||||
case IrCmd::JUMP_CMP_NUM:
|
||||
case IrCmd::JUMP_SLOT_MATCH:
|
||||
case IrCmd::RETURN:
|
||||
case IrCmd::FORGLOOP:
|
||||
case IrCmd::FORGLOOP_FALLBACK:
|
||||
case IrCmd::FORGPREP_XNEXT_FALLBACK:
|
||||
case IrCmd::FALLBACK_FORGPREP:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool isNonTerminatingJump(IrCmd cmd)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case IrCmd::TRY_NUM_TO_INDEX:
|
||||
case IrCmd::TRY_CALL_FASTGETTM:
|
||||
case IrCmd::CHECK_FASTCALL_RES:
|
||||
case IrCmd::CHECK_TAG:
|
||||
case IrCmd::CHECK_TRUTHY:
|
||||
case IrCmd::CHECK_READONLY:
|
||||
case IrCmd::CHECK_NO_METATABLE:
|
||||
case IrCmd::CHECK_SAFE_ENV:
|
||||
case IrCmd::CHECK_ARRAY_SIZE:
|
||||
case IrCmd::CHECK_SLOT_MATCH:
|
||||
case IrCmd::CHECK_NODE_NO_NEXT:
|
||||
case IrCmd::CHECK_NODE_VALUE:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool hasResult(IrCmd cmd)
|
||||
{
|
||||
switch (cmd)
|
||||
{
|
||||
case IrCmd::LOAD_TAG:
|
||||
case IrCmd::LOAD_POINTER:
|
||||
case IrCmd::LOAD_DOUBLE:
|
||||
case IrCmd::LOAD_INT:
|
||||
case IrCmd::LOAD_TVALUE:
|
||||
case IrCmd::LOAD_ENV:
|
||||
case IrCmd::GET_ARR_ADDR:
|
||||
case IrCmd::GET_SLOT_NODE_ADDR:
|
||||
case IrCmd::GET_HASH_NODE_ADDR:
|
||||
case IrCmd::GET_CLOSURE_UPVAL_ADDR:
|
||||
case IrCmd::ADD_INT:
|
||||
case IrCmd::SUB_INT:
|
||||
case IrCmd::ADD_NUM:
|
||||
case IrCmd::SUB_NUM:
|
||||
case IrCmd::MUL_NUM:
|
||||
case IrCmd::DIV_NUM:
|
||||
case IrCmd::IDIV_NUM:
|
||||
case IrCmd::MOD_NUM:
|
||||
case IrCmd::MIN_NUM:
|
||||
case IrCmd::MAX_NUM:
|
||||
case IrCmd::UNM_NUM:
|
||||
case IrCmd::FLOOR_NUM:
|
||||
case IrCmd::CEIL_NUM:
|
||||
case IrCmd::ROUND_NUM:
|
||||
case IrCmd::SQRT_NUM:
|
||||
case IrCmd::ABS_NUM:
|
||||
case IrCmd::NOT_ANY:
|
||||
case IrCmd::CMP_ANY:
|
||||
case IrCmd::TABLE_LEN:
|
||||
case IrCmd::TABLE_SETNUM:
|
||||
case IrCmd::STRING_LEN:
|
||||
case IrCmd::NEW_TABLE:
|
||||
case IrCmd::DUP_TABLE:
|
||||
case IrCmd::TRY_NUM_TO_INDEX:
|
||||
case IrCmd::TRY_CALL_FASTGETTM:
|
||||
case IrCmd::INT_TO_NUM:
|
||||
case IrCmd::UINT_TO_NUM:
|
||||
case IrCmd::NUM_TO_INT:
|
||||
case IrCmd::NUM_TO_UINT:
|
||||
case IrCmd::SUBSTITUTE:
|
||||
case IrCmd::INVOKE_FASTCALL:
|
||||
case IrCmd::BITAND_UINT:
|
||||
case IrCmd::BITXOR_UINT:
|
||||
case IrCmd::BITOR_UINT:
|
||||
case IrCmd::BITNOT_UINT:
|
||||
case IrCmd::BITLSHIFT_UINT:
|
||||
case IrCmd::BITRSHIFT_UINT:
|
||||
case IrCmd::BITARSHIFT_UINT:
|
||||
case IrCmd::BITLROTATE_UINT:
|
||||
case IrCmd::BITRROTATE_UINT:
|
||||
case IrCmd::BITCOUNTLZ_UINT:
|
||||
case IrCmd::BITCOUNTRZ_UINT:
|
||||
case IrCmd::INVOKE_LIBM:
|
||||
case IrCmd::GET_TYPE:
|
||||
case IrCmd::GET_TYPEOF:
|
||||
case IrCmd::NEWCLOSURE:
|
||||
case IrCmd::FINDUPVAL:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool hasSideEffects(IrCmd cmd)
|
||||
{
|
||||
if (cmd == IrCmd::INVOKE_FASTCALL)
|
||||
return true;
|
||||
|
||||
// Instructions that don't produce a result most likely have other side-effects to make them useful
|
||||
// Right now, a full switch would mirror the 'hasResult' function, so we use this simple condition
|
||||
return !hasResult(cmd);
|
||||
}
|
||||
|
||||
inline bool isPseudo(IrCmd cmd)
|
||||
{
|
||||
// Instructions that are used for internal needs and are not a part of final lowering
|
||||
return cmd == IrCmd::NOP || cmd == IrCmd::SUBSTITUTE;
|
||||
}
|
||||
|
||||
IrValueKind getCmdValueKind(IrCmd cmd);
|
||||
|
||||
bool isGCO(uint8_t tag);
|
||||
|
||||
// Manually add or remove use of an operand
|
||||
void addUse(IrFunction& function, IrOp op);
|
||||
void removeUse(IrFunction& function, IrOp op);
|
||||
|
||||
// Remove a single instruction
|
||||
void kill(IrFunction& function, IrInst& inst);
|
||||
|
||||
// Remove a range of instructions
|
||||
void kill(IrFunction& function, uint32_t start, uint32_t end);
|
||||
|
||||
// Remove a block, including all instructions inside
|
||||
void kill(IrFunction& function, IrBlock& block);
|
||||
|
||||
// Replace a single operand and update use counts (can cause chain removal of dead code)
|
||||
void replace(IrFunction& function, IrOp& original, IrOp replacement);
|
||||
|
||||
// Replace a single instruction
|
||||
// Target instruction index instead of reference is used to handle introduction of a new block terminator
|
||||
void replace(IrFunction& function, IrBlock& block, uint32_t instIdx, IrInst replacement);
|
||||
|
||||
// Replace instruction with a different value (using IrCmd::SUBSTITUTE)
|
||||
void substitute(IrFunction& function, IrInst& inst, IrOp replacement);
|
||||
|
||||
// Replace instruction arguments that point to substitutions with target values
|
||||
void applySubstitutions(IrFunction& function, IrOp& op);
|
||||
void applySubstitutions(IrFunction& function, IrInst& inst);
|
||||
|
||||
// Compare numbers using IR condition value
|
||||
bool compare(double a, double b, IrCondition cond);
|
||||
|
||||
// Perform constant folding on instruction at index
|
||||
// For most instructions, successful folding results in a IrCmd::SUBSTITUTE
|
||||
// But it can also be successful on conditional control-flow, replacing it with an unconditional IrCmd::JUMP
|
||||
void foldConstants(IrBuilder& build, IrFunction& function, IrBlock& block, uint32_t instIdx);
|
||||
|
||||
uint32_t getNativeContextOffset(int bfid);
|
||||
|
||||
// Cleans up blocks that were created with no users
|
||||
void killUnusedBlocks(IrFunction& function);
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
18
external/luau/include/Luau/Label.h
vendored
Normal file
18
external/luau/include/Luau/Label.h
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct Label
|
||||
{
|
||||
uint32_t id = 0;
|
||||
uint32_t location = ~0u;
|
||||
};
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
268
external/luau/include/Luau/Lexer.h
vendored
Normal file
268
external/luau/include/Luau/Lexer.h
vendored
Normal file
|
@ -0,0 +1,268 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Ast.h"
|
||||
#include "Luau/Location.h"
|
||||
#include "Luau/DenseHash.h"
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
class Allocator
|
||||
{
|
||||
public:
|
||||
Allocator();
|
||||
Allocator(Allocator&&);
|
||||
|
||||
Allocator& operator=(Allocator&&) = delete;
|
||||
|
||||
~Allocator();
|
||||
|
||||
void* allocate(size_t size);
|
||||
|
||||
template<typename T, typename... Args>
|
||||
T* alloc(Args&&... args)
|
||||
{
|
||||
static_assert(std::is_trivially_destructible<T>::value, "Objects allocated with this allocator will never have their destructors run!");
|
||||
|
||||
T* t = static_cast<T*>(allocate(sizeof(T)));
|
||||
new (t) T(std::forward<Args>(args)...);
|
||||
return t;
|
||||
}
|
||||
|
||||
private:
|
||||
struct Page
|
||||
{
|
||||
Page* next;
|
||||
|
||||
char data[8192];
|
||||
};
|
||||
|
||||
Page* root;
|
||||
size_t offset;
|
||||
};
|
||||
|
||||
struct Lexeme
|
||||
{
|
||||
enum Type
|
||||
{
|
||||
Eof = 0,
|
||||
|
||||
// 1..255 means actual character values
|
||||
Char_END = 256,
|
||||
|
||||
Equal,
|
||||
LessEqual,
|
||||
GreaterEqual,
|
||||
NotEqual,
|
||||
Dot2,
|
||||
Dot3,
|
||||
SkinnyArrow,
|
||||
DoubleColon,
|
||||
FloorDiv,
|
||||
|
||||
InterpStringBegin,
|
||||
InterpStringMid,
|
||||
InterpStringEnd,
|
||||
// An interpolated string with no expressions (like `x`)
|
||||
InterpStringSimple,
|
||||
|
||||
AddAssign,
|
||||
SubAssign,
|
||||
MulAssign,
|
||||
DivAssign,
|
||||
FloorDivAssign,
|
||||
ModAssign,
|
||||
PowAssign,
|
||||
ConcatAssign,
|
||||
|
||||
RawString,
|
||||
QuotedString,
|
||||
Number,
|
||||
Name,
|
||||
|
||||
Comment,
|
||||
BlockComment,
|
||||
|
||||
BrokenString,
|
||||
BrokenComment,
|
||||
BrokenUnicode,
|
||||
BrokenInterpDoubleBrace,
|
||||
|
||||
Error,
|
||||
|
||||
Reserved_BEGIN,
|
||||
ReservedAnd = Reserved_BEGIN,
|
||||
ReservedBreak,
|
||||
ReservedDo,
|
||||
ReservedElse,
|
||||
ReservedElseif,
|
||||
ReservedEnd,
|
||||
ReservedFalse,
|
||||
ReservedFor,
|
||||
ReservedFunction,
|
||||
ReservedIf,
|
||||
ReservedIn,
|
||||
ReservedLocal,
|
||||
ReservedNil,
|
||||
ReservedNot,
|
||||
ReservedOr,
|
||||
ReservedRepeat,
|
||||
ReservedReturn,
|
||||
ReservedThen,
|
||||
ReservedTrue,
|
||||
ReservedUntil,
|
||||
ReservedWhile,
|
||||
Reserved_END
|
||||
};
|
||||
|
||||
Type type;
|
||||
Location location;
|
||||
unsigned int length;
|
||||
|
||||
union
|
||||
{
|
||||
const char* data; // String, Number, Comment
|
||||
const char* name; // Name
|
||||
unsigned int codepoint; // BrokenUnicode
|
||||
};
|
||||
|
||||
Lexeme(const Location& location, Type type);
|
||||
Lexeme(const Location& location, char character);
|
||||
Lexeme(const Location& location, Type type, const char* data, size_t size);
|
||||
Lexeme(const Location& location, Type type, const char* name);
|
||||
|
||||
std::string toString() const;
|
||||
};
|
||||
|
||||
class AstNameTable
|
||||
{
|
||||
public:
|
||||
AstNameTable(Allocator& allocator);
|
||||
|
||||
AstName addStatic(const char* name, Lexeme::Type type = Lexeme::Name);
|
||||
|
||||
std::pair<AstName, Lexeme::Type> getOrAddWithType(const char* name, size_t length);
|
||||
std::pair<AstName, Lexeme::Type> getWithType(const char* name, size_t length) const;
|
||||
|
||||
AstName getOrAdd(const char* name);
|
||||
AstName get(const char* name) const;
|
||||
|
||||
private:
|
||||
struct Entry
|
||||
{
|
||||
AstName value;
|
||||
uint32_t length;
|
||||
Lexeme::Type type;
|
||||
|
||||
bool operator==(const Entry& other) const;
|
||||
};
|
||||
|
||||
struct EntryHash
|
||||
{
|
||||
size_t operator()(const Entry& e) const;
|
||||
};
|
||||
|
||||
DenseHashSet<Entry, EntryHash> data;
|
||||
|
||||
Allocator& allocator;
|
||||
};
|
||||
|
||||
class Lexer
|
||||
{
|
||||
public:
|
||||
Lexer(const char* buffer, std::size_t bufferSize, AstNameTable& names);
|
||||
|
||||
void setSkipComments(bool skip);
|
||||
void setReadNames(bool read);
|
||||
|
||||
const Location& previousLocation() const
|
||||
{
|
||||
return prevLocation;
|
||||
}
|
||||
|
||||
const Lexeme& next();
|
||||
const Lexeme& next(bool skipComments, bool updatePrevLocation);
|
||||
void nextline();
|
||||
|
||||
Lexeme lookahead();
|
||||
|
||||
const Lexeme& current() const
|
||||
{
|
||||
return lexeme;
|
||||
}
|
||||
|
||||
static bool isReserved(const std::string& word);
|
||||
|
||||
static bool fixupQuotedString(std::string& data);
|
||||
static void fixupMultilineString(std::string& data);
|
||||
|
||||
private:
|
||||
char peekch() const;
|
||||
char peekch(unsigned int lookahead) const;
|
||||
|
||||
Position position() const;
|
||||
|
||||
// consume() assumes current character is not a newline for performance; when that is not known, consumeAny() should be used instead.
|
||||
void consume();
|
||||
void consumeAny();
|
||||
|
||||
Lexeme readCommentBody();
|
||||
|
||||
// Given a sequence [===[ or ]===], returns:
|
||||
// 1. number of equal signs (or 0 if none present) between the brackets
|
||||
// 2. -1 if this is not a long comment/string separator
|
||||
// 3. -N if this is a malformed separator
|
||||
// Does *not* consume the closing brace.
|
||||
int skipLongSeparator();
|
||||
|
||||
Lexeme readLongString(const Position& start, int sep, Lexeme::Type ok, Lexeme::Type broken);
|
||||
Lexeme readQuotedString();
|
||||
|
||||
Lexeme readInterpolatedStringBegin();
|
||||
Lexeme readInterpolatedStringSection(Position start, Lexeme::Type formatType, Lexeme::Type endType);
|
||||
|
||||
void readBackslashInString();
|
||||
|
||||
std::pair<AstName, Lexeme::Type> readName();
|
||||
|
||||
Lexeme readNumber(const Position& start, unsigned int startOffset);
|
||||
|
||||
Lexeme readUtf8Error();
|
||||
Lexeme readNext();
|
||||
|
||||
const char* buffer;
|
||||
std::size_t bufferSize;
|
||||
|
||||
unsigned int offset;
|
||||
|
||||
unsigned int line;
|
||||
unsigned int lineOffset;
|
||||
|
||||
Lexeme lexeme;
|
||||
|
||||
Location prevLocation;
|
||||
|
||||
AstNameTable& names;
|
||||
|
||||
bool skipComments;
|
||||
bool readNames;
|
||||
|
||||
enum class BraceType
|
||||
{
|
||||
InterpolatedString,
|
||||
Normal
|
||||
};
|
||||
|
||||
std::vector<BraceType> braceStack;
|
||||
};
|
||||
|
||||
inline bool isSpace(char ch)
|
||||
{
|
||||
return ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '\v' || ch == '\f';
|
||||
}
|
||||
|
||||
} // namespace Luau
|
124
external/luau/include/Luau/LinterConfig.h
vendored
Normal file
124
external/luau/include/Luau/LinterConfig.h
vendored
Normal file
|
@ -0,0 +1,124 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Location.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
struct HotComment;
|
||||
|
||||
struct LintWarning
|
||||
{
|
||||
// Make sure any new lint codes are documented here: https://luau-lang.org/lint
|
||||
// Note that in Studio, the active set of lint warnings is determined by FStringStudioLuauLints
|
||||
enum Code
|
||||
{
|
||||
Code_Unknown = 0,
|
||||
|
||||
Code_UnknownGlobal = 1, // superseded by type checker
|
||||
Code_DeprecatedGlobal = 2,
|
||||
Code_GlobalUsedAsLocal = 3,
|
||||
Code_LocalShadow = 4, // disabled in Studio
|
||||
Code_SameLineStatement = 5, // disabled in Studio
|
||||
Code_MultiLineStatement = 6,
|
||||
Code_LocalUnused = 7, // disabled in Studio
|
||||
Code_FunctionUnused = 8, // disabled in Studio
|
||||
Code_ImportUnused = 9, // disabled in Studio
|
||||
Code_BuiltinGlobalWrite = 10,
|
||||
Code_PlaceholderRead = 11,
|
||||
Code_UnreachableCode = 12,
|
||||
Code_UnknownType = 13,
|
||||
Code_ForRange = 14,
|
||||
Code_UnbalancedAssignment = 15,
|
||||
Code_ImplicitReturn = 16, // disabled in Studio, superseded by type checker in strict mode
|
||||
Code_DuplicateLocal = 17,
|
||||
Code_FormatString = 18,
|
||||
Code_TableLiteral = 19,
|
||||
Code_UninitializedLocal = 20,
|
||||
Code_DuplicateFunction = 21,
|
||||
Code_DeprecatedApi = 22,
|
||||
Code_TableOperations = 23,
|
||||
Code_DuplicateCondition = 24,
|
||||
Code_MisleadingAndOr = 25,
|
||||
Code_CommentDirective = 26,
|
||||
Code_IntegerParsing = 27,
|
||||
Code_ComparisonPrecedence = 28,
|
||||
|
||||
Code__Count
|
||||
};
|
||||
|
||||
Code code;
|
||||
Location location;
|
||||
std::string text;
|
||||
|
||||
static const char* getName(Code code);
|
||||
static Code parseName(const char* name);
|
||||
static uint64_t parseMask(const std::vector<HotComment>& hotcomments);
|
||||
};
|
||||
|
||||
struct LintOptions
|
||||
{
|
||||
uint64_t warningMask = 0;
|
||||
|
||||
void enableWarning(LintWarning::Code code)
|
||||
{
|
||||
warningMask |= 1ull << code;
|
||||
}
|
||||
void disableWarning(LintWarning::Code code)
|
||||
{
|
||||
warningMask &= ~(1ull << code);
|
||||
}
|
||||
|
||||
bool isEnabled(LintWarning::Code code) const
|
||||
{
|
||||
return 0 != (warningMask & (1ull << code));
|
||||
}
|
||||
|
||||
void setDefaults();
|
||||
};
|
||||
|
||||
// clang-format off
|
||||
static const char* kWarningNames[] = {
|
||||
"Unknown",
|
||||
|
||||
"UnknownGlobal",
|
||||
"DeprecatedGlobal",
|
||||
"GlobalUsedAsLocal",
|
||||
"LocalShadow",
|
||||
"SameLineStatement",
|
||||
"MultiLineStatement",
|
||||
"LocalUnused",
|
||||
"FunctionUnused",
|
||||
"ImportUnused",
|
||||
"BuiltinGlobalWrite",
|
||||
"PlaceholderRead",
|
||||
"UnreachableCode",
|
||||
"UnknownType",
|
||||
"ForRange",
|
||||
"UnbalancedAssignment",
|
||||
"ImplicitReturn",
|
||||
"DuplicateLocal",
|
||||
"FormatString",
|
||||
"TableLiteral",
|
||||
"UninitializedLocal",
|
||||
"DuplicateFunction",
|
||||
"DeprecatedApi",
|
||||
"TableOperations",
|
||||
"DuplicateCondition",
|
||||
"MisleadingAndOr",
|
||||
"CommentDirective",
|
||||
"IntegerParsing",
|
||||
"ComparisonPrecedence",
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
static_assert(std::size(kWarningNames) == unsigned(LintWarning::Code__Count), "did you forget to add warning to the list?");
|
||||
|
||||
} // namespace Luau
|
44
external/luau/include/Luau/Location.h
vendored
Normal file
44
external/luau/include/Luau/Location.h
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
struct Position
|
||||
{
|
||||
unsigned int line, column;
|
||||
|
||||
Position(unsigned int line, unsigned int column);
|
||||
|
||||
bool operator==(const Position& rhs) const;
|
||||
bool operator!=(const Position& rhs) const;
|
||||
bool operator<(const Position& rhs) const;
|
||||
bool operator>(const Position& rhs) const;
|
||||
bool operator<=(const Position& rhs) const;
|
||||
bool operator>=(const Position& rhs) const;
|
||||
|
||||
void shift(const Position& start, const Position& oldEnd, const Position& newEnd);
|
||||
};
|
||||
|
||||
struct Location
|
||||
{
|
||||
Position begin, end;
|
||||
|
||||
Location();
|
||||
Location(const Position& begin, const Position& end);
|
||||
Location(const Position& begin, unsigned int length);
|
||||
Location(const Location& begin, const Location& end);
|
||||
|
||||
bool operator==(const Location& rhs) const;
|
||||
bool operator!=(const Location& rhs) const;
|
||||
|
||||
bool encloses(const Location& l) const;
|
||||
bool overlaps(const Location& l) const;
|
||||
bool contains(const Position& p) const;
|
||||
bool containsClosed(const Position& p) const;
|
||||
void extend(const Location& other);
|
||||
void shift(const Position& start, const Position& oldEnd, const Position& newEnd);
|
||||
};
|
||||
|
||||
} // namespace Luau
|
145
external/luau/include/Luau/OperandX64.h
vendored
Normal file
145
external/luau/include/Luau/OperandX64.h
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
#include "Luau/RegisterX64.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace X64
|
||||
{
|
||||
|
||||
enum class CategoryX64 : uint8_t
|
||||
{
|
||||
reg,
|
||||
mem,
|
||||
imm,
|
||||
};
|
||||
|
||||
struct OperandX64
|
||||
{
|
||||
constexpr OperandX64(RegisterX64 reg)
|
||||
: cat(CategoryX64::reg)
|
||||
, index(noreg)
|
||||
, base(reg)
|
||||
, memSize(SizeX64::none)
|
||||
, scale(1)
|
||||
, imm(0)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr OperandX64(int32_t imm)
|
||||
: cat(CategoryX64::imm)
|
||||
, index(noreg)
|
||||
, base(noreg)
|
||||
, memSize(SizeX64::none)
|
||||
, scale(1)
|
||||
, imm(imm)
|
||||
{
|
||||
}
|
||||
|
||||
constexpr explicit OperandX64(SizeX64 size, RegisterX64 index, uint8_t scale, RegisterX64 base, int32_t disp)
|
||||
: cat(CategoryX64::mem)
|
||||
, index(index)
|
||||
, base(base)
|
||||
, memSize(size)
|
||||
, scale(scale)
|
||||
, imm(disp)
|
||||
{
|
||||
}
|
||||
|
||||
// Fields are carefully placed to make this struct fit into an 8 byte register
|
||||
CategoryX64 cat;
|
||||
RegisterX64 index;
|
||||
RegisterX64 base;
|
||||
SizeX64 memSize : 4;
|
||||
uint8_t scale : 4;
|
||||
int32_t imm;
|
||||
|
||||
constexpr OperandX64 operator[](OperandX64&& addr) const
|
||||
{
|
||||
LUAU_ASSERT(cat == CategoryX64::mem);
|
||||
LUAU_ASSERT(index == noreg && scale == 1 && base == noreg && imm == 0);
|
||||
LUAU_ASSERT(addr.memSize == SizeX64::none);
|
||||
|
||||
addr.cat = CategoryX64::mem;
|
||||
addr.memSize = memSize;
|
||||
return addr;
|
||||
}
|
||||
};
|
||||
|
||||
constexpr OperandX64 addr{SizeX64::none, noreg, 1, noreg, 0};
|
||||
constexpr OperandX64 byte{SizeX64::byte, noreg, 1, noreg, 0};
|
||||
constexpr OperandX64 word{SizeX64::word, noreg, 1, noreg, 0};
|
||||
constexpr OperandX64 dword{SizeX64::dword, noreg, 1, noreg, 0};
|
||||
constexpr OperandX64 qword{SizeX64::qword, noreg, 1, noreg, 0};
|
||||
constexpr OperandX64 xmmword{SizeX64::xmmword, noreg, 1, noreg, 0};
|
||||
constexpr OperandX64 ymmword{SizeX64::ymmword, noreg, 1, noreg, 0};
|
||||
|
||||
constexpr OperandX64 operator*(RegisterX64 reg, uint8_t scale)
|
||||
{
|
||||
if (scale == 1)
|
||||
return OperandX64(reg);
|
||||
|
||||
LUAU_ASSERT(scale == 1 || scale == 2 || scale == 4 || scale == 8);
|
||||
LUAU_ASSERT(reg.index != 0b100 && "can't scale SP");
|
||||
|
||||
return OperandX64(SizeX64::none, reg, scale, noreg, 0);
|
||||
}
|
||||
|
||||
constexpr OperandX64 operator+(RegisterX64 reg, int32_t disp)
|
||||
{
|
||||
return OperandX64(SizeX64::none, noreg, 1, reg, disp);
|
||||
}
|
||||
|
||||
constexpr OperandX64 operator-(RegisterX64 reg, int32_t disp)
|
||||
{
|
||||
return OperandX64(SizeX64::none, noreg, 1, reg, -disp);
|
||||
}
|
||||
|
||||
constexpr OperandX64 operator+(RegisterX64 base, RegisterX64 index)
|
||||
{
|
||||
LUAU_ASSERT(index.index != 4 && "sp cannot be used as index");
|
||||
LUAU_ASSERT(base.size == index.size);
|
||||
|
||||
return OperandX64(SizeX64::none, index, 1, base, 0);
|
||||
}
|
||||
|
||||
constexpr OperandX64 operator+(OperandX64 op, int32_t disp)
|
||||
{
|
||||
LUAU_ASSERT(op.cat == CategoryX64::mem);
|
||||
LUAU_ASSERT(op.memSize == SizeX64::none);
|
||||
|
||||
op.imm += disp;
|
||||
return op;
|
||||
}
|
||||
|
||||
constexpr OperandX64 operator+(OperandX64 op, RegisterX64 base)
|
||||
{
|
||||
LUAU_ASSERT(op.cat == CategoryX64::mem);
|
||||
LUAU_ASSERT(op.memSize == SizeX64::none);
|
||||
LUAU_ASSERT(op.base == noreg);
|
||||
LUAU_ASSERT(op.index == noreg || op.index.size == base.size);
|
||||
|
||||
op.base = base;
|
||||
return op;
|
||||
}
|
||||
|
||||
constexpr OperandX64 operator+(RegisterX64 base, OperandX64 op)
|
||||
{
|
||||
LUAU_ASSERT(op.cat == CategoryX64::mem);
|
||||
LUAU_ASSERT(op.memSize == SizeX64::none);
|
||||
LUAU_ASSERT(op.base == noreg);
|
||||
LUAU_ASSERT(op.index == noreg || op.index.size == base.size);
|
||||
|
||||
op.base = base;
|
||||
return op;
|
||||
}
|
||||
|
||||
} // namespace X64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
17
external/luau/include/Luau/OptimizeConstProp.h
vendored
Normal file
17
external/luau/include/Luau/OptimizeConstProp.h
vendored
Normal file
|
@ -0,0 +1,17 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/IrData.h"
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct IrBuilder;
|
||||
|
||||
void constPropInBlockChains(IrBuilder& build, bool useValueNumbering);
|
||||
void createLinearBlocks(IrBuilder& build, bool useValueNumbering);
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
14
external/luau/include/Luau/OptimizeFinalX64.h
vendored
Normal file
14
external/luau/include/Luau/OptimizeFinalX64.h
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/IrData.h"
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
void optimizeMemoryOperandsX64(IrFunction& function);
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
21
external/luau/include/Luau/ParseOptions.h
vendored
Normal file
21
external/luau/include/Luau/ParseOptions.h
vendored
Normal file
|
@ -0,0 +1,21 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
enum class Mode
|
||||
{
|
||||
NoCheck, // Do not perform any inference
|
||||
Nonstrict, // Unannotated symbols are any
|
||||
Strict, // Unannotated symbols are inferred
|
||||
Definition, // Type definition module, has special parsing rules
|
||||
};
|
||||
|
||||
struct ParseOptions
|
||||
{
|
||||
bool allowDeclarationSyntax = false;
|
||||
bool captureComments = false;
|
||||
};
|
||||
|
||||
} // namespace Luau
|
71
external/luau/include/Luau/ParseResult.h
vendored
Normal file
71
external/luau/include/Luau/ParseResult.h
vendored
Normal file
|
@ -0,0 +1,71 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
#include "Luau/Location.h"
|
||||
#include "Luau/Lexer.h"
|
||||
#include "Luau/StringUtils.h"
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
class AstStatBlock;
|
||||
|
||||
class ParseError : public std::exception
|
||||
{
|
||||
public:
|
||||
ParseError(const Location& location, const std::string& message);
|
||||
|
||||
virtual const char* what() const throw();
|
||||
|
||||
const Location& getLocation() const;
|
||||
const std::string& getMessage() const;
|
||||
|
||||
static LUAU_NORETURN void raise(const Location& location, const char* format, ...) LUAU_PRINTF_ATTR(2, 3);
|
||||
|
||||
private:
|
||||
Location location;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
class ParseErrors : public std::exception
|
||||
{
|
||||
public:
|
||||
ParseErrors(std::vector<ParseError> errors);
|
||||
|
||||
virtual const char* what() const throw();
|
||||
|
||||
const std::vector<ParseError>& getErrors() const;
|
||||
|
||||
private:
|
||||
std::vector<ParseError> errors;
|
||||
std::string message;
|
||||
};
|
||||
|
||||
struct HotComment
|
||||
{
|
||||
bool header;
|
||||
Location location;
|
||||
std::string content;
|
||||
};
|
||||
|
||||
struct Comment
|
||||
{
|
||||
Lexeme::Type type; // Comment, BlockComment, or BrokenComment
|
||||
Location location;
|
||||
};
|
||||
|
||||
struct ParseResult
|
||||
{
|
||||
AstStatBlock* root;
|
||||
size_t lines = 0;
|
||||
|
||||
std::vector<HotComment> hotcomments;
|
||||
std::vector<ParseError> errors;
|
||||
|
||||
std::vector<Comment> commentLocations;
|
||||
};
|
||||
|
||||
static constexpr const char* kParseNameError = "%error-id%";
|
||||
|
||||
} // namespace Luau
|
415
external/luau/include/Luau/Parser.h
vendored
Normal file
415
external/luau/include/Luau/Parser.h
vendored
Normal file
|
@ -0,0 +1,415 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Ast.h"
|
||||
#include "Luau/Lexer.h"
|
||||
#include "Luau/ParseOptions.h"
|
||||
#include "Luau/ParseResult.h"
|
||||
#include "Luau/StringUtils.h"
|
||||
#include "Luau/DenseHash.h"
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <optional>
|
||||
#include <tuple>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
template<typename T>
|
||||
class TempVector
|
||||
{
|
||||
public:
|
||||
explicit TempVector(std::vector<T>& storage);
|
||||
|
||||
~TempVector();
|
||||
|
||||
const T& operator[](std::size_t index) const;
|
||||
|
||||
const T& front() const;
|
||||
|
||||
const T& back() const;
|
||||
|
||||
bool empty() const;
|
||||
|
||||
std::size_t size() const;
|
||||
|
||||
void push_back(const T& item);
|
||||
|
||||
typename std::vector<T>::const_iterator begin() const
|
||||
{
|
||||
return storage.begin() + offset;
|
||||
}
|
||||
typename std::vector<T>::const_iterator end() const
|
||||
{
|
||||
return storage.begin() + offset + size_;
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T>& storage;
|
||||
size_t offset;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
static ParseResult parse(
|
||||
const char* buffer, std::size_t bufferSize, AstNameTable& names, Allocator& allocator, ParseOptions options = ParseOptions());
|
||||
|
||||
private:
|
||||
struct Name;
|
||||
struct Binding;
|
||||
|
||||
Parser(const char* buffer, std::size_t bufferSize, AstNameTable& names, Allocator& allocator, const ParseOptions& options);
|
||||
|
||||
bool blockFollow(const Lexeme& l);
|
||||
|
||||
AstStatBlock* parseChunk();
|
||||
|
||||
// chunk ::= {stat [`;']} [laststat [`;']]
|
||||
// block ::= chunk
|
||||
AstStatBlock* parseBlock();
|
||||
|
||||
AstStatBlock* parseBlockNoScope();
|
||||
|
||||
// stat ::=
|
||||
// varlist `=' explist |
|
||||
// functioncall |
|
||||
// do block end |
|
||||
// while exp do block end |
|
||||
// repeat block until exp |
|
||||
// if exp then block {elseif exp then block} [else block] end |
|
||||
// for Name `=' exp `,' exp [`,' exp] do block end |
|
||||
// for namelist in explist do block end |
|
||||
// function funcname funcbody |
|
||||
// local function Name funcbody |
|
||||
// local namelist [`=' explist]
|
||||
// laststat ::= return [explist] | break
|
||||
AstStat* parseStat();
|
||||
|
||||
// if exp then block {elseif exp then block} [else block] end
|
||||
AstStat* parseIf();
|
||||
|
||||
// while exp do block end
|
||||
AstStat* parseWhile();
|
||||
|
||||
// repeat block until exp
|
||||
AstStat* parseRepeat();
|
||||
|
||||
// do block end
|
||||
AstStat* parseDo();
|
||||
|
||||
// break
|
||||
AstStat* parseBreak();
|
||||
|
||||
// continue
|
||||
AstStat* parseContinue(const Location& start);
|
||||
|
||||
// for Name `=' exp `,' exp [`,' exp] do block end |
|
||||
// for namelist in explist do block end |
|
||||
AstStat* parseFor();
|
||||
|
||||
// funcname ::= Name {`.' Name} [`:' Name]
|
||||
AstExpr* parseFunctionName(Location start, bool& hasself, AstName& debugname);
|
||||
|
||||
// function funcname funcbody
|
||||
AstStat* parseFunctionStat();
|
||||
|
||||
// local function Name funcbody |
|
||||
// local namelist [`=' explist]
|
||||
AstStat* parseLocal();
|
||||
|
||||
// return [explist]
|
||||
AstStat* parseReturn();
|
||||
|
||||
// type Name `=' Type
|
||||
AstStat* parseTypeAlias(const Location& start, bool exported);
|
||||
|
||||
AstDeclaredClassProp parseDeclaredClassMethod();
|
||||
|
||||
// `declare global' Name: Type |
|
||||
// `declare function' Name`(' [parlist] `)' [`:` Type]
|
||||
AstStat* parseDeclaration(const Location& start);
|
||||
|
||||
// varlist `=' explist
|
||||
AstStat* parseAssignment(AstExpr* initial);
|
||||
|
||||
// var [`+=' | `-=' | `*=' | `/=' | `%=' | `^=' | `..='] exp
|
||||
AstStat* parseCompoundAssignment(AstExpr* initial, AstExprBinary::Op op);
|
||||
|
||||
std::pair<AstLocal*, AstArray<AstLocal*>> prepareFunctionArguments(const Location& start, bool hasself, const TempVector<Binding>& args);
|
||||
|
||||
// funcbodyhead ::= `(' [namelist [`,' `...'] | `...'] `)' [`:` Type]
|
||||
// funcbody ::= funcbodyhead block end
|
||||
std::pair<AstExprFunction*, AstLocal*> parseFunctionBody(
|
||||
bool hasself, const Lexeme& matchFunction, const AstName& debugname, const Name* localName);
|
||||
|
||||
// explist ::= {exp `,'} exp
|
||||
void parseExprList(TempVector<AstExpr*>& result);
|
||||
|
||||
// binding ::= Name [`:` Type]
|
||||
Binding parseBinding();
|
||||
|
||||
// bindinglist ::= (binding | `...') {`,' bindinglist}
|
||||
// Returns the location of the vararg ..., or std::nullopt if the function is not vararg.
|
||||
std::tuple<bool, Location, AstTypePack*> parseBindingList(TempVector<Binding>& result, bool allowDot3 = false);
|
||||
|
||||
AstType* parseOptionalType();
|
||||
|
||||
// TypeList ::= Type [`,' TypeList]
|
||||
// ReturnType ::= Type | `(' TypeList `)'
|
||||
// TableProp ::= Name `:' Type
|
||||
// TableIndexer ::= `[' Type `]' `:' Type
|
||||
// PropList ::= (TableProp | TableIndexer) [`,' PropList]
|
||||
// Type
|
||||
// ::= Name
|
||||
// | `nil`
|
||||
// | `{' [PropList] `}'
|
||||
// | `(' [TypeList] `)' `->` ReturnType
|
||||
|
||||
// Returns the variadic annotation, if it exists.
|
||||
AstTypePack* parseTypeList(TempVector<AstType*>& result, TempVector<std::optional<AstArgumentName>>& resultNames);
|
||||
|
||||
std::optional<AstTypeList> parseOptionalReturnType();
|
||||
std::pair<Location, AstTypeList> parseReturnType();
|
||||
|
||||
AstTableIndexer* parseTableIndexer();
|
||||
|
||||
AstTypeOrPack parseFunctionType(bool allowPack);
|
||||
AstType* parseFunctionTypeTail(const Lexeme& begin, AstArray<AstGenericType> generics, AstArray<AstGenericTypePack> genericPacks,
|
||||
AstArray<AstType*> params, AstArray<std::optional<AstArgumentName>> paramNames, AstTypePack* varargAnnotation);
|
||||
|
||||
AstType* parseTableType();
|
||||
AstTypeOrPack parseSimpleType(bool allowPack);
|
||||
|
||||
AstTypeOrPack parseTypeOrPack();
|
||||
AstType* parseType();
|
||||
|
||||
AstTypePack* parseTypePack();
|
||||
AstTypePack* parseVariadicArgumentTypePack();
|
||||
|
||||
AstType* parseTypeSuffix(AstType* type, const Location& begin);
|
||||
|
||||
static std::optional<AstExprUnary::Op> parseUnaryOp(const Lexeme& l);
|
||||
static std::optional<AstExprBinary::Op> parseBinaryOp(const Lexeme& l);
|
||||
static std::optional<AstExprBinary::Op> parseCompoundOp(const Lexeme& l);
|
||||
|
||||
struct BinaryOpPriority
|
||||
{
|
||||
unsigned char left, right;
|
||||
};
|
||||
|
||||
std::optional<AstExprUnary::Op> checkUnaryConfusables();
|
||||
std::optional<AstExprBinary::Op> checkBinaryConfusables(const BinaryOpPriority binaryPriority[], unsigned int limit);
|
||||
|
||||
// subexpr -> (asexp | unop subexpr) { binop subexpr }
|
||||
// where `binop' is any binary operator with a priority higher than `limit'
|
||||
AstExpr* parseExpr(unsigned int limit = 0);
|
||||
|
||||
// NAME
|
||||
AstExpr* parseNameExpr(const char* context = nullptr);
|
||||
|
||||
// prefixexp -> NAME | '(' expr ')'
|
||||
AstExpr* parsePrefixExpr();
|
||||
|
||||
// primaryexp -> prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs }
|
||||
AstExpr* parsePrimaryExpr(bool asStatement);
|
||||
|
||||
// asexp -> simpleexp [`::' Type]
|
||||
AstExpr* parseAssertionExpr();
|
||||
|
||||
// simpleexp -> NUMBER | STRING | NIL | true | false | ... | constructor | FUNCTION body | primaryexp
|
||||
AstExpr* parseSimpleExpr();
|
||||
|
||||
// args ::= `(' [explist] `)' | tableconstructor | String
|
||||
AstExpr* parseFunctionArgs(AstExpr* func, bool self);
|
||||
|
||||
// tableconstructor ::= `{' [fieldlist] `}'
|
||||
// fieldlist ::= field {fieldsep field} [fieldsep]
|
||||
// field ::= `[' exp `]' `=' exp | Name `=' exp | exp
|
||||
// fieldsep ::= `,' | `;'
|
||||
AstExpr* parseTableConstructor();
|
||||
|
||||
// TODO: Add grammar rules here?
|
||||
AstExpr* parseIfElseExpr();
|
||||
|
||||
// stringinterp ::= <INTERP_BEGIN> exp {<INTERP_MID> exp} <INTERP_END>
|
||||
AstExpr* parseInterpString();
|
||||
|
||||
// Name
|
||||
std::optional<Name> parseNameOpt(const char* context = nullptr);
|
||||
Name parseName(const char* context = nullptr);
|
||||
Name parseIndexName(const char* context, const Position& previous);
|
||||
|
||||
// `<' namelist `>'
|
||||
std::pair<AstArray<AstGenericType>, AstArray<AstGenericTypePack>> parseGenericTypeList(bool withDefaultValues);
|
||||
|
||||
// `<' Type[, ...] `>'
|
||||
AstArray<AstTypeOrPack> parseTypeParams();
|
||||
|
||||
std::optional<AstArray<char>> parseCharArray();
|
||||
AstExpr* parseString();
|
||||
AstExpr* parseNumber();
|
||||
|
||||
AstLocal* pushLocal(const Binding& binding);
|
||||
|
||||
unsigned int saveLocals();
|
||||
|
||||
void restoreLocals(unsigned int offset);
|
||||
|
||||
// check that parser is at lexeme/symbol, move to next lexeme/symbol on success, report failure and continue on failure
|
||||
bool expectAndConsume(char value, const char* context = nullptr);
|
||||
bool expectAndConsume(Lexeme::Type type, const char* context = nullptr);
|
||||
void expectAndConsumeFail(Lexeme::Type type, const char* context);
|
||||
|
||||
struct MatchLexeme
|
||||
{
|
||||
MatchLexeme(const Lexeme& l)
|
||||
: type(l.type)
|
||||
, position(l.location.begin)
|
||||
{
|
||||
}
|
||||
|
||||
Lexeme::Type type;
|
||||
Position position;
|
||||
};
|
||||
|
||||
bool expectMatchAndConsume(char value, const MatchLexeme& begin, bool searchForMissing = false);
|
||||
void expectMatchAndConsumeFail(Lexeme::Type type, const MatchLexeme& begin, const char* extra = nullptr);
|
||||
bool expectMatchAndConsumeRecover(char value, const MatchLexeme& begin, bool searchForMissing);
|
||||
|
||||
bool expectMatchEndAndConsume(Lexeme::Type type, const MatchLexeme& begin);
|
||||
void expectMatchEndAndConsumeFail(Lexeme::Type type, const MatchLexeme& begin);
|
||||
|
||||
template<typename T>
|
||||
AstArray<T> copy(const T* data, std::size_t size);
|
||||
|
||||
template<typename T>
|
||||
AstArray<T> copy(const TempVector<T>& data);
|
||||
|
||||
template<typename T>
|
||||
AstArray<T> copy(std::initializer_list<T> data);
|
||||
|
||||
AstArray<char> copy(const std::string& data);
|
||||
|
||||
void incrementRecursionCounter(const char* context);
|
||||
|
||||
void report(const Location& location, const char* format, va_list args);
|
||||
void report(const Location& location, const char* format, ...) LUAU_PRINTF_ATTR(3, 4);
|
||||
|
||||
void reportNameError(const char* context);
|
||||
|
||||
AstStatError* reportStatError(const Location& location, const AstArray<AstExpr*>& expressions, const AstArray<AstStat*>& statements,
|
||||
const char* format, ...) LUAU_PRINTF_ATTR(5, 6);
|
||||
AstExprError* reportExprError(const Location& location, const AstArray<AstExpr*>& expressions, const char* format, ...) LUAU_PRINTF_ATTR(4, 5);
|
||||
AstTypeError* reportTypeError(const Location& location, const AstArray<AstType*>& types, const char* format, ...) LUAU_PRINTF_ATTR(4, 5);
|
||||
// `parseErrorLocation` is associated with the parser error
|
||||
// `astErrorLocation` is associated with the AstTypeError created
|
||||
// It can be useful to have different error locations so that the parse error can include the next lexeme, while the AstTypeError can precisely
|
||||
// define the location (possibly of zero size) where a type annotation is expected.
|
||||
AstTypeError* reportMissingTypeError(const Location& parseErrorLocation, const Location& astErrorLocation, const char* format, ...)
|
||||
LUAU_PRINTF_ATTR(4, 5);
|
||||
|
||||
AstExpr* reportFunctionArgsError(AstExpr* func, bool self);
|
||||
void reportAmbiguousCallError();
|
||||
|
||||
void nextLexeme();
|
||||
|
||||
struct Function
|
||||
{
|
||||
bool vararg;
|
||||
unsigned int loopDepth;
|
||||
|
||||
Function()
|
||||
: vararg(false)
|
||||
, loopDepth(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Local
|
||||
{
|
||||
AstLocal* local;
|
||||
unsigned int offset;
|
||||
|
||||
Local()
|
||||
: local(nullptr)
|
||||
, offset(0)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Name
|
||||
{
|
||||
AstName name;
|
||||
Location location;
|
||||
|
||||
Name(const AstName& name, const Location& location)
|
||||
: name(name)
|
||||
, location(location)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
struct Binding
|
||||
{
|
||||
Name name;
|
||||
AstType* annotation;
|
||||
|
||||
explicit Binding(const Name& name, AstType* annotation = nullptr)
|
||||
: name(name)
|
||||
, annotation(annotation)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
ParseOptions options;
|
||||
|
||||
Lexer lexer;
|
||||
Allocator& allocator;
|
||||
|
||||
std::vector<Comment> commentLocations;
|
||||
std::vector<HotComment> hotcomments;
|
||||
|
||||
bool hotcommentHeader = true;
|
||||
|
||||
unsigned int recursionCounter;
|
||||
|
||||
AstName nameSelf;
|
||||
AstName nameNumber;
|
||||
AstName nameError;
|
||||
AstName nameNil;
|
||||
|
||||
MatchLexeme endMismatchSuspect;
|
||||
|
||||
std::vector<Function> functionStack;
|
||||
|
||||
DenseHashMap<AstName, AstLocal*> localMap;
|
||||
std::vector<AstLocal*> localStack;
|
||||
|
||||
std::vector<ParseError> parseErrors;
|
||||
|
||||
std::vector<unsigned int> matchRecoveryStopOnToken;
|
||||
|
||||
std::vector<AstStat*> scratchStat;
|
||||
std::vector<AstArray<char>> scratchString;
|
||||
std::vector<AstExpr*> scratchExpr;
|
||||
std::vector<AstExpr*> scratchExprAux;
|
||||
std::vector<AstName> scratchName;
|
||||
std::vector<AstName> scratchPackName;
|
||||
std::vector<Binding> scratchBinding;
|
||||
std::vector<AstLocal*> scratchLocal;
|
||||
std::vector<AstTableProp> scratchTableTypeProps;
|
||||
std::vector<AstType*> scratchType;
|
||||
std::vector<AstTypeOrPack> scratchTypeOrPack;
|
||||
std::vector<AstDeclaredClassProp> scratchDeclaredClassProps;
|
||||
std::vector<AstExprTable::Item> scratchItem;
|
||||
std::vector<AstArgumentName> scratchArgName;
|
||||
std::vector<AstGenericType> scratchGenericTypes;
|
||||
std::vector<AstGenericTypePack> scratchGenericTypePacks;
|
||||
std::vector<std::optional<AstArgumentName>> scratchOptArgName;
|
||||
std::string scratchData;
|
||||
};
|
||||
|
||||
} // namespace Luau
|
221
external/luau/include/Luau/RegisterA64.h
vendored
Normal file
221
external/luau/include/Luau/RegisterA64.h
vendored
Normal file
|
@ -0,0 +1,221 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace A64
|
||||
{
|
||||
|
||||
enum class KindA64 : uint8_t
|
||||
{
|
||||
none,
|
||||
w, // 32-bit GPR
|
||||
x, // 64-bit GPR
|
||||
s, // 32-bit SIMD&FP scalar
|
||||
d, // 64-bit SIMD&FP scalar
|
||||
q, // 128-bit SIMD&FP vector
|
||||
};
|
||||
|
||||
struct RegisterA64
|
||||
{
|
||||
KindA64 kind : 3;
|
||||
uint8_t index : 5;
|
||||
|
||||
constexpr bool operator==(RegisterA64 rhs) const
|
||||
{
|
||||
return kind == rhs.kind && index == rhs.index;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(RegisterA64 rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr RegisterA64 castReg(KindA64 kind, RegisterA64 reg)
|
||||
{
|
||||
LUAU_ASSERT(kind != reg.kind);
|
||||
LUAU_ASSERT(kind != KindA64::none && reg.kind != KindA64::none);
|
||||
LUAU_ASSERT((kind == KindA64::w || kind == KindA64::x) == (reg.kind == KindA64::w || reg.kind == KindA64::x));
|
||||
|
||||
return RegisterA64{kind, reg.index};
|
||||
}
|
||||
|
||||
constexpr RegisterA64 noreg{KindA64::none, 0};
|
||||
|
||||
constexpr RegisterA64 w0{KindA64::w, 0};
|
||||
constexpr RegisterA64 w1{KindA64::w, 1};
|
||||
constexpr RegisterA64 w2{KindA64::w, 2};
|
||||
constexpr RegisterA64 w3{KindA64::w, 3};
|
||||
constexpr RegisterA64 w4{KindA64::w, 4};
|
||||
constexpr RegisterA64 w5{KindA64::w, 5};
|
||||
constexpr RegisterA64 w6{KindA64::w, 6};
|
||||
constexpr RegisterA64 w7{KindA64::w, 7};
|
||||
constexpr RegisterA64 w8{KindA64::w, 8};
|
||||
constexpr RegisterA64 w9{KindA64::w, 9};
|
||||
constexpr RegisterA64 w10{KindA64::w, 10};
|
||||
constexpr RegisterA64 w11{KindA64::w, 11};
|
||||
constexpr RegisterA64 w12{KindA64::w, 12};
|
||||
constexpr RegisterA64 w13{KindA64::w, 13};
|
||||
constexpr RegisterA64 w14{KindA64::w, 14};
|
||||
constexpr RegisterA64 w15{KindA64::w, 15};
|
||||
constexpr RegisterA64 w16{KindA64::w, 16};
|
||||
constexpr RegisterA64 w17{KindA64::w, 17};
|
||||
constexpr RegisterA64 w18{KindA64::w, 18};
|
||||
constexpr RegisterA64 w19{KindA64::w, 19};
|
||||
constexpr RegisterA64 w20{KindA64::w, 20};
|
||||
constexpr RegisterA64 w21{KindA64::w, 21};
|
||||
constexpr RegisterA64 w22{KindA64::w, 22};
|
||||
constexpr RegisterA64 w23{KindA64::w, 23};
|
||||
constexpr RegisterA64 w24{KindA64::w, 24};
|
||||
constexpr RegisterA64 w25{KindA64::w, 25};
|
||||
constexpr RegisterA64 w26{KindA64::w, 26};
|
||||
constexpr RegisterA64 w27{KindA64::w, 27};
|
||||
constexpr RegisterA64 w28{KindA64::w, 28};
|
||||
constexpr RegisterA64 w29{KindA64::w, 29};
|
||||
constexpr RegisterA64 w30{KindA64::w, 30};
|
||||
constexpr RegisterA64 wzr{KindA64::w, 31};
|
||||
|
||||
constexpr RegisterA64 x0{KindA64::x, 0};
|
||||
constexpr RegisterA64 x1{KindA64::x, 1};
|
||||
constexpr RegisterA64 x2{KindA64::x, 2};
|
||||
constexpr RegisterA64 x3{KindA64::x, 3};
|
||||
constexpr RegisterA64 x4{KindA64::x, 4};
|
||||
constexpr RegisterA64 x5{KindA64::x, 5};
|
||||
constexpr RegisterA64 x6{KindA64::x, 6};
|
||||
constexpr RegisterA64 x7{KindA64::x, 7};
|
||||
constexpr RegisterA64 x8{KindA64::x, 8};
|
||||
constexpr RegisterA64 x9{KindA64::x, 9};
|
||||
constexpr RegisterA64 x10{KindA64::x, 10};
|
||||
constexpr RegisterA64 x11{KindA64::x, 11};
|
||||
constexpr RegisterA64 x12{KindA64::x, 12};
|
||||
constexpr RegisterA64 x13{KindA64::x, 13};
|
||||
constexpr RegisterA64 x14{KindA64::x, 14};
|
||||
constexpr RegisterA64 x15{KindA64::x, 15};
|
||||
constexpr RegisterA64 x16{KindA64::x, 16};
|
||||
constexpr RegisterA64 x17{KindA64::x, 17};
|
||||
constexpr RegisterA64 x18{KindA64::x, 18};
|
||||
constexpr RegisterA64 x19{KindA64::x, 19};
|
||||
constexpr RegisterA64 x20{KindA64::x, 20};
|
||||
constexpr RegisterA64 x21{KindA64::x, 21};
|
||||
constexpr RegisterA64 x22{KindA64::x, 22};
|
||||
constexpr RegisterA64 x23{KindA64::x, 23};
|
||||
constexpr RegisterA64 x24{KindA64::x, 24};
|
||||
constexpr RegisterA64 x25{KindA64::x, 25};
|
||||
constexpr RegisterA64 x26{KindA64::x, 26};
|
||||
constexpr RegisterA64 x27{KindA64::x, 27};
|
||||
constexpr RegisterA64 x28{KindA64::x, 28};
|
||||
constexpr RegisterA64 x29{KindA64::x, 29};
|
||||
constexpr RegisterA64 x30{KindA64::x, 30};
|
||||
constexpr RegisterA64 xzr{KindA64::x, 31};
|
||||
|
||||
constexpr RegisterA64 sp{KindA64::none, 31};
|
||||
|
||||
constexpr RegisterA64 s0{KindA64::s, 0};
|
||||
constexpr RegisterA64 s1{KindA64::s, 1};
|
||||
constexpr RegisterA64 s2{KindA64::s, 2};
|
||||
constexpr RegisterA64 s3{KindA64::s, 3};
|
||||
constexpr RegisterA64 s4{KindA64::s, 4};
|
||||
constexpr RegisterA64 s5{KindA64::s, 5};
|
||||
constexpr RegisterA64 s6{KindA64::s, 6};
|
||||
constexpr RegisterA64 s7{KindA64::s, 7};
|
||||
constexpr RegisterA64 s8{KindA64::s, 8};
|
||||
constexpr RegisterA64 s9{KindA64::s, 9};
|
||||
constexpr RegisterA64 s10{KindA64::s, 10};
|
||||
constexpr RegisterA64 s11{KindA64::s, 11};
|
||||
constexpr RegisterA64 s12{KindA64::s, 12};
|
||||
constexpr RegisterA64 s13{KindA64::s, 13};
|
||||
constexpr RegisterA64 s14{KindA64::s, 14};
|
||||
constexpr RegisterA64 s15{KindA64::s, 15};
|
||||
constexpr RegisterA64 s16{KindA64::s, 16};
|
||||
constexpr RegisterA64 s17{KindA64::s, 17};
|
||||
constexpr RegisterA64 s18{KindA64::s, 18};
|
||||
constexpr RegisterA64 s19{KindA64::s, 19};
|
||||
constexpr RegisterA64 s20{KindA64::s, 20};
|
||||
constexpr RegisterA64 s21{KindA64::s, 21};
|
||||
constexpr RegisterA64 s22{KindA64::s, 22};
|
||||
constexpr RegisterA64 s23{KindA64::s, 23};
|
||||
constexpr RegisterA64 s24{KindA64::s, 24};
|
||||
constexpr RegisterA64 s25{KindA64::s, 25};
|
||||
constexpr RegisterA64 s26{KindA64::s, 26};
|
||||
constexpr RegisterA64 s27{KindA64::s, 27};
|
||||
constexpr RegisterA64 s28{KindA64::s, 28};
|
||||
constexpr RegisterA64 s29{KindA64::s, 29};
|
||||
constexpr RegisterA64 s30{KindA64::s, 30};
|
||||
constexpr RegisterA64 s31{KindA64::s, 31};
|
||||
|
||||
constexpr RegisterA64 d0{KindA64::d, 0};
|
||||
constexpr RegisterA64 d1{KindA64::d, 1};
|
||||
constexpr RegisterA64 d2{KindA64::d, 2};
|
||||
constexpr RegisterA64 d3{KindA64::d, 3};
|
||||
constexpr RegisterA64 d4{KindA64::d, 4};
|
||||
constexpr RegisterA64 d5{KindA64::d, 5};
|
||||
constexpr RegisterA64 d6{KindA64::d, 6};
|
||||
constexpr RegisterA64 d7{KindA64::d, 7};
|
||||
constexpr RegisterA64 d8{KindA64::d, 8};
|
||||
constexpr RegisterA64 d9{KindA64::d, 9};
|
||||
constexpr RegisterA64 d10{KindA64::d, 10};
|
||||
constexpr RegisterA64 d11{KindA64::d, 11};
|
||||
constexpr RegisterA64 d12{KindA64::d, 12};
|
||||
constexpr RegisterA64 d13{KindA64::d, 13};
|
||||
constexpr RegisterA64 d14{KindA64::d, 14};
|
||||
constexpr RegisterA64 d15{KindA64::d, 15};
|
||||
constexpr RegisterA64 d16{KindA64::d, 16};
|
||||
constexpr RegisterA64 d17{KindA64::d, 17};
|
||||
constexpr RegisterA64 d18{KindA64::d, 18};
|
||||
constexpr RegisterA64 d19{KindA64::d, 19};
|
||||
constexpr RegisterA64 d20{KindA64::d, 20};
|
||||
constexpr RegisterA64 d21{KindA64::d, 21};
|
||||
constexpr RegisterA64 d22{KindA64::d, 22};
|
||||
constexpr RegisterA64 d23{KindA64::d, 23};
|
||||
constexpr RegisterA64 d24{KindA64::d, 24};
|
||||
constexpr RegisterA64 d25{KindA64::d, 25};
|
||||
constexpr RegisterA64 d26{KindA64::d, 26};
|
||||
constexpr RegisterA64 d27{KindA64::d, 27};
|
||||
constexpr RegisterA64 d28{KindA64::d, 28};
|
||||
constexpr RegisterA64 d29{KindA64::d, 29};
|
||||
constexpr RegisterA64 d30{KindA64::d, 30};
|
||||
constexpr RegisterA64 d31{KindA64::d, 31};
|
||||
|
||||
constexpr RegisterA64 q0{KindA64::q, 0};
|
||||
constexpr RegisterA64 q1{KindA64::q, 1};
|
||||
constexpr RegisterA64 q2{KindA64::q, 2};
|
||||
constexpr RegisterA64 q3{KindA64::q, 3};
|
||||
constexpr RegisterA64 q4{KindA64::q, 4};
|
||||
constexpr RegisterA64 q5{KindA64::q, 5};
|
||||
constexpr RegisterA64 q6{KindA64::q, 6};
|
||||
constexpr RegisterA64 q7{KindA64::q, 7};
|
||||
constexpr RegisterA64 q8{KindA64::q, 8};
|
||||
constexpr RegisterA64 q9{KindA64::q, 9};
|
||||
constexpr RegisterA64 q10{KindA64::q, 10};
|
||||
constexpr RegisterA64 q11{KindA64::q, 11};
|
||||
constexpr RegisterA64 q12{KindA64::q, 12};
|
||||
constexpr RegisterA64 q13{KindA64::q, 13};
|
||||
constexpr RegisterA64 q14{KindA64::q, 14};
|
||||
constexpr RegisterA64 q15{KindA64::q, 15};
|
||||
constexpr RegisterA64 q16{KindA64::q, 16};
|
||||
constexpr RegisterA64 q17{KindA64::q, 17};
|
||||
constexpr RegisterA64 q18{KindA64::q, 18};
|
||||
constexpr RegisterA64 q19{KindA64::q, 19};
|
||||
constexpr RegisterA64 q20{KindA64::q, 20};
|
||||
constexpr RegisterA64 q21{KindA64::q, 21};
|
||||
constexpr RegisterA64 q22{KindA64::q, 22};
|
||||
constexpr RegisterA64 q23{KindA64::q, 23};
|
||||
constexpr RegisterA64 q24{KindA64::q, 24};
|
||||
constexpr RegisterA64 q25{KindA64::q, 25};
|
||||
constexpr RegisterA64 q26{KindA64::q, 26};
|
||||
constexpr RegisterA64 q27{KindA64::q, 27};
|
||||
constexpr RegisterA64 q28{KindA64::q, 28};
|
||||
constexpr RegisterA64 q29{KindA64::q, 29};
|
||||
constexpr RegisterA64 q30{KindA64::q, 30};
|
||||
constexpr RegisterA64 q31{KindA64::q, 31};
|
||||
|
||||
} // namespace A64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
152
external/luau/include/Luau/RegisterX64.h
vendored
Normal file
152
external/luau/include/Luau/RegisterX64.h
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
namespace X64
|
||||
{
|
||||
|
||||
enum class SizeX64 : uint8_t
|
||||
{
|
||||
none,
|
||||
byte,
|
||||
word,
|
||||
dword,
|
||||
qword,
|
||||
xmmword,
|
||||
ymmword,
|
||||
};
|
||||
|
||||
struct RegisterX64
|
||||
{
|
||||
SizeX64 size : 3;
|
||||
uint8_t index : 5;
|
||||
|
||||
constexpr bool operator==(RegisterX64 rhs) const
|
||||
{
|
||||
return size == rhs.size && index == rhs.index;
|
||||
}
|
||||
|
||||
constexpr bool operator!=(RegisterX64 rhs) const
|
||||
{
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
constexpr RegisterX64 noreg{SizeX64::none, 16};
|
||||
constexpr RegisterX64 rip{SizeX64::none, 0};
|
||||
|
||||
constexpr RegisterX64 al{SizeX64::byte, 0};
|
||||
constexpr RegisterX64 cl{SizeX64::byte, 1};
|
||||
constexpr RegisterX64 dl{SizeX64::byte, 2};
|
||||
constexpr RegisterX64 bl{SizeX64::byte, 3};
|
||||
constexpr RegisterX64 spl{SizeX64::byte, 4};
|
||||
constexpr RegisterX64 bpl{SizeX64::byte, 5};
|
||||
constexpr RegisterX64 sil{SizeX64::byte, 6};
|
||||
constexpr RegisterX64 dil{SizeX64::byte, 7};
|
||||
constexpr RegisterX64 r8b{SizeX64::byte, 8};
|
||||
constexpr RegisterX64 r9b{SizeX64::byte, 9};
|
||||
constexpr RegisterX64 r10b{SizeX64::byte, 10};
|
||||
constexpr RegisterX64 r11b{SizeX64::byte, 11};
|
||||
constexpr RegisterX64 r12b{SizeX64::byte, 12};
|
||||
constexpr RegisterX64 r13b{SizeX64::byte, 13};
|
||||
constexpr RegisterX64 r14b{SizeX64::byte, 14};
|
||||
constexpr RegisterX64 r15b{SizeX64::byte, 15};
|
||||
|
||||
constexpr RegisterX64 eax{SizeX64::dword, 0};
|
||||
constexpr RegisterX64 ecx{SizeX64::dword, 1};
|
||||
constexpr RegisterX64 edx{SizeX64::dword, 2};
|
||||
constexpr RegisterX64 ebx{SizeX64::dword, 3};
|
||||
constexpr RegisterX64 esp{SizeX64::dword, 4};
|
||||
constexpr RegisterX64 ebp{SizeX64::dword, 5};
|
||||
constexpr RegisterX64 esi{SizeX64::dword, 6};
|
||||
constexpr RegisterX64 edi{SizeX64::dword, 7};
|
||||
constexpr RegisterX64 r8d{SizeX64::dword, 8};
|
||||
constexpr RegisterX64 r9d{SizeX64::dword, 9};
|
||||
constexpr RegisterX64 r10d{SizeX64::dword, 10};
|
||||
constexpr RegisterX64 r11d{SizeX64::dword, 11};
|
||||
constexpr RegisterX64 r12d{SizeX64::dword, 12};
|
||||
constexpr RegisterX64 r13d{SizeX64::dword, 13};
|
||||
constexpr RegisterX64 r14d{SizeX64::dword, 14};
|
||||
constexpr RegisterX64 r15d{SizeX64::dword, 15};
|
||||
|
||||
constexpr RegisterX64 rax{SizeX64::qword, 0};
|
||||
constexpr RegisterX64 rcx{SizeX64::qword, 1};
|
||||
constexpr RegisterX64 rdx{SizeX64::qword, 2};
|
||||
constexpr RegisterX64 rbx{SizeX64::qword, 3};
|
||||
constexpr RegisterX64 rsp{SizeX64::qword, 4};
|
||||
constexpr RegisterX64 rbp{SizeX64::qword, 5};
|
||||
constexpr RegisterX64 rsi{SizeX64::qword, 6};
|
||||
constexpr RegisterX64 rdi{SizeX64::qword, 7};
|
||||
constexpr RegisterX64 r8{SizeX64::qword, 8};
|
||||
constexpr RegisterX64 r9{SizeX64::qword, 9};
|
||||
constexpr RegisterX64 r10{SizeX64::qword, 10};
|
||||
constexpr RegisterX64 r11{SizeX64::qword, 11};
|
||||
constexpr RegisterX64 r12{SizeX64::qword, 12};
|
||||
constexpr RegisterX64 r13{SizeX64::qword, 13};
|
||||
constexpr RegisterX64 r14{SizeX64::qword, 14};
|
||||
constexpr RegisterX64 r15{SizeX64::qword, 15};
|
||||
|
||||
constexpr RegisterX64 xmm0{SizeX64::xmmword, 0};
|
||||
constexpr RegisterX64 xmm1{SizeX64::xmmword, 1};
|
||||
constexpr RegisterX64 xmm2{SizeX64::xmmword, 2};
|
||||
constexpr RegisterX64 xmm3{SizeX64::xmmword, 3};
|
||||
constexpr RegisterX64 xmm4{SizeX64::xmmword, 4};
|
||||
constexpr RegisterX64 xmm5{SizeX64::xmmword, 5};
|
||||
constexpr RegisterX64 xmm6{SizeX64::xmmword, 6};
|
||||
constexpr RegisterX64 xmm7{SizeX64::xmmword, 7};
|
||||
constexpr RegisterX64 xmm8{SizeX64::xmmword, 8};
|
||||
constexpr RegisterX64 xmm9{SizeX64::xmmword, 9};
|
||||
constexpr RegisterX64 xmm10{SizeX64::xmmword, 10};
|
||||
constexpr RegisterX64 xmm11{SizeX64::xmmword, 11};
|
||||
constexpr RegisterX64 xmm12{SizeX64::xmmword, 12};
|
||||
constexpr RegisterX64 xmm13{SizeX64::xmmword, 13};
|
||||
constexpr RegisterX64 xmm14{SizeX64::xmmword, 14};
|
||||
constexpr RegisterX64 xmm15{SizeX64::xmmword, 15};
|
||||
|
||||
constexpr RegisterX64 ymm0{SizeX64::ymmword, 0};
|
||||
constexpr RegisterX64 ymm1{SizeX64::ymmword, 1};
|
||||
constexpr RegisterX64 ymm2{SizeX64::ymmword, 2};
|
||||
constexpr RegisterX64 ymm3{SizeX64::ymmword, 3};
|
||||
constexpr RegisterX64 ymm4{SizeX64::ymmword, 4};
|
||||
constexpr RegisterX64 ymm5{SizeX64::ymmword, 5};
|
||||
constexpr RegisterX64 ymm6{SizeX64::ymmword, 6};
|
||||
constexpr RegisterX64 ymm7{SizeX64::ymmword, 7};
|
||||
constexpr RegisterX64 ymm8{SizeX64::ymmword, 8};
|
||||
constexpr RegisterX64 ymm9{SizeX64::ymmword, 9};
|
||||
constexpr RegisterX64 ymm10{SizeX64::ymmword, 10};
|
||||
constexpr RegisterX64 ymm11{SizeX64::ymmword, 11};
|
||||
constexpr RegisterX64 ymm12{SizeX64::ymmword, 12};
|
||||
constexpr RegisterX64 ymm13{SizeX64::ymmword, 13};
|
||||
constexpr RegisterX64 ymm14{SizeX64::ymmword, 14};
|
||||
constexpr RegisterX64 ymm15{SizeX64::ymmword, 15};
|
||||
|
||||
constexpr RegisterX64 byteReg(RegisterX64 reg)
|
||||
{
|
||||
return RegisterX64{SizeX64::byte, reg.index};
|
||||
}
|
||||
|
||||
constexpr RegisterX64 wordReg(RegisterX64 reg)
|
||||
{
|
||||
return RegisterX64{SizeX64::word, reg.index};
|
||||
}
|
||||
|
||||
constexpr RegisterX64 dwordReg(RegisterX64 reg)
|
||||
{
|
||||
return RegisterX64{SizeX64::dword, reg.index};
|
||||
}
|
||||
|
||||
constexpr RegisterX64 qwordReg(RegisterX64 reg)
|
||||
{
|
||||
return RegisterX64{SizeX64::qword, reg.index};
|
||||
}
|
||||
|
||||
} // namespace X64
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
36
external/luau/include/Luau/StringUtils.h
vendored
Normal file
36
external/luau/include/Luau/StringUtils.h
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
|
||||
std::string format(const char* fmt, ...) LUAU_PRINTF_ATTR(1, 2);
|
||||
std::string vformat(const char* fmt, va_list args);
|
||||
|
||||
void formatAppend(std::string& str, const char* fmt, ...) LUAU_PRINTF_ATTR(2, 3);
|
||||
void vformatAppend(std::string& ret, const char* fmt, va_list args);
|
||||
|
||||
std::string join(const std::vector<std::string_view>& segments, std::string_view delimiter);
|
||||
std::string join(const std::vector<std::string>& segments, std::string_view delimiter);
|
||||
|
||||
std::vector<std::string_view> split(std::string_view s, char delimiter);
|
||||
|
||||
// Computes the Damerau-Levenshtein distance of A and B.
|
||||
// https://en.wikipedia.org/wiki/Damerau-Levenshtein_distance#Distance_with_adjacent_transpositions
|
||||
size_t editDistance(std::string_view a, std::string_view b);
|
||||
|
||||
bool startsWith(std::string_view lhs, std::string_view rhs);
|
||||
bool equalsLower(std::string_view lhs, std::string_view rhs);
|
||||
|
||||
size_t hashRange(const char* data, size_t size);
|
||||
|
||||
std::string escape(std::string_view s, bool escapeForInterpString = false);
|
||||
bool isIdentifier(std::string_view s);
|
||||
} // namespace Luau
|
231
external/luau/include/Luau/TimeTrace.h
vendored
Normal file
231
external/luau/include/Luau/TimeTrace.h
vendored
Normal file
|
@ -0,0 +1,231 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/Common.h"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
LUAU_FASTFLAG(DebugLuauTimeTracing)
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace TimeTrace
|
||||
{
|
||||
double getClock();
|
||||
uint32_t getClockMicroseconds();
|
||||
} // namespace TimeTrace
|
||||
} // namespace Luau
|
||||
|
||||
#if defined(LUAU_ENABLE_TIME_TRACE)
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace TimeTrace
|
||||
{
|
||||
struct Token
|
||||
{
|
||||
const char* name;
|
||||
const char* category;
|
||||
};
|
||||
|
||||
enum class EventType : uint8_t
|
||||
{
|
||||
Enter,
|
||||
Leave,
|
||||
|
||||
ArgName,
|
||||
ArgValue,
|
||||
};
|
||||
|
||||
struct Event
|
||||
{
|
||||
EventType type;
|
||||
uint16_t token;
|
||||
|
||||
union
|
||||
{
|
||||
uint32_t microsec; // 1 hour trace limit
|
||||
uint32_t dataPos;
|
||||
} data;
|
||||
};
|
||||
|
||||
struct GlobalContext;
|
||||
struct ThreadContext;
|
||||
|
||||
std::shared_ptr<GlobalContext> getGlobalContext();
|
||||
|
||||
uint16_t createToken(GlobalContext& context, const char* name, const char* category);
|
||||
uint32_t createThread(GlobalContext& context, ThreadContext* threadContext);
|
||||
void releaseThread(GlobalContext& context, ThreadContext* threadContext);
|
||||
void flushEvents(GlobalContext& context, uint32_t threadId, const std::vector<Event>& events, const std::vector<char>& data);
|
||||
|
||||
struct ThreadContext
|
||||
{
|
||||
ThreadContext()
|
||||
: globalContext(getGlobalContext())
|
||||
{
|
||||
threadId = createThread(*globalContext, this);
|
||||
}
|
||||
|
||||
~ThreadContext()
|
||||
{
|
||||
if (!events.empty())
|
||||
flushEvents();
|
||||
|
||||
releaseThread(*globalContext, this);
|
||||
}
|
||||
|
||||
void flushEvents()
|
||||
{
|
||||
static uint16_t flushToken = createToken(*globalContext, "flushEvents", "TimeTrace");
|
||||
|
||||
events.push_back({EventType::Enter, flushToken, {getClockMicroseconds()}});
|
||||
|
||||
TimeTrace::flushEvents(*globalContext, threadId, events, data);
|
||||
|
||||
events.clear();
|
||||
data.clear();
|
||||
|
||||
events.push_back({EventType::Leave, 0, {getClockMicroseconds()}});
|
||||
}
|
||||
|
||||
void eventEnter(uint16_t token)
|
||||
{
|
||||
eventEnter(token, getClockMicroseconds());
|
||||
}
|
||||
|
||||
void eventEnter(uint16_t token, uint32_t microsec)
|
||||
{
|
||||
events.push_back({EventType::Enter, token, {microsec}});
|
||||
}
|
||||
|
||||
void eventLeave()
|
||||
{
|
||||
eventLeave(getClockMicroseconds());
|
||||
}
|
||||
|
||||
void eventLeave(uint32_t microsec)
|
||||
{
|
||||
events.push_back({EventType::Leave, 0, {microsec}});
|
||||
|
||||
if (events.size() > kEventFlushLimit)
|
||||
flushEvents();
|
||||
}
|
||||
|
||||
void eventArgument(const char* name, const char* value)
|
||||
{
|
||||
uint32_t pos = uint32_t(data.size());
|
||||
data.insert(data.end(), name, name + strlen(name) + 1);
|
||||
events.push_back({EventType::ArgName, 0, {pos}});
|
||||
|
||||
pos = uint32_t(data.size());
|
||||
data.insert(data.end(), value, value + strlen(value) + 1);
|
||||
events.push_back({EventType::ArgValue, 0, {pos}});
|
||||
}
|
||||
|
||||
std::shared_ptr<GlobalContext> globalContext;
|
||||
uint32_t threadId;
|
||||
std::vector<Event> events;
|
||||
std::vector<char> data;
|
||||
|
||||
static constexpr size_t kEventFlushLimit = 8192;
|
||||
};
|
||||
|
||||
ThreadContext& getThreadContext();
|
||||
|
||||
struct Scope
|
||||
{
|
||||
explicit Scope(uint16_t token)
|
||||
: context(getThreadContext())
|
||||
{
|
||||
if (!FFlag::DebugLuauTimeTracing)
|
||||
return;
|
||||
|
||||
context.eventEnter(token);
|
||||
}
|
||||
|
||||
~Scope()
|
||||
{
|
||||
if (!FFlag::DebugLuauTimeTracing)
|
||||
return;
|
||||
|
||||
context.eventLeave();
|
||||
}
|
||||
|
||||
ThreadContext& context;
|
||||
};
|
||||
|
||||
struct OptionalTailScope
|
||||
{
|
||||
explicit OptionalTailScope(uint16_t token, uint32_t threshold)
|
||||
: context(getThreadContext())
|
||||
, token(token)
|
||||
, threshold(threshold)
|
||||
{
|
||||
if (!FFlag::DebugLuauTimeTracing)
|
||||
return;
|
||||
|
||||
pos = uint32_t(context.events.size());
|
||||
microsec = getClockMicroseconds();
|
||||
}
|
||||
|
||||
~OptionalTailScope()
|
||||
{
|
||||
if (!FFlag::DebugLuauTimeTracing)
|
||||
return;
|
||||
|
||||
if (pos == context.events.size())
|
||||
{
|
||||
uint32_t curr = getClockMicroseconds();
|
||||
|
||||
if (curr - microsec > threshold)
|
||||
{
|
||||
context.eventEnter(token, microsec);
|
||||
context.eventLeave(curr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ThreadContext& context;
|
||||
uint16_t token;
|
||||
uint32_t threshold;
|
||||
uint32_t microsec;
|
||||
uint32_t pos;
|
||||
};
|
||||
|
||||
LUAU_NOINLINE uint16_t createScopeData(const char* name, const char* category);
|
||||
|
||||
} // namespace TimeTrace
|
||||
} // namespace Luau
|
||||
|
||||
// Regular scope
|
||||
#define LUAU_TIMETRACE_SCOPE(name, category) \
|
||||
static uint16_t lttScopeStatic = Luau::TimeTrace::createScopeData(name, category); \
|
||||
Luau::TimeTrace::Scope lttScope(lttScopeStatic)
|
||||
|
||||
// A scope without nested scopes that may be skipped if the time it took is less than the threshold
|
||||
#define LUAU_TIMETRACE_OPTIONAL_TAIL_SCOPE(name, category, microsec) \
|
||||
static uint16_t lttScopeStaticOptTail = Luau::TimeTrace::createScopeData(name, category); \
|
||||
Luau::TimeTrace::OptionalTailScope lttScope(lttScopeStaticOptTail, microsec)
|
||||
|
||||
// Extra key/value data can be added to regular scopes
|
||||
#define LUAU_TIMETRACE_ARGUMENT(name, value) \
|
||||
do \
|
||||
{ \
|
||||
if (FFlag::DebugLuauTimeTracing) \
|
||||
lttScope.context.eventArgument(name, value); \
|
||||
} while (false)
|
||||
|
||||
#else
|
||||
|
||||
#define LUAU_TIMETRACE_SCOPE(name, category)
|
||||
#define LUAU_TIMETRACE_OPTIONAL_TAIL_SCOPE(name, category, microsec)
|
||||
#define LUAU_TIMETRACE_ARGUMENT(name, value) \
|
||||
do \
|
||||
{ \
|
||||
} while (false)
|
||||
|
||||
#endif
|
63
external/luau/include/Luau/UnwindBuilder.h
vendored
Normal file
63
external/luau/include/Luau/UnwindBuilder.h
vendored
Normal file
|
@ -0,0 +1,63 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/RegisterA64.h"
|
||||
#include "Luau/RegisterX64.h"
|
||||
|
||||
#include <initializer_list>
|
||||
#include <vector>
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
// This value is used in 'finishFunction' to mark the function that spans to the end of the whole code block
|
||||
static uint32_t kFullBlockFuncton = ~0u;
|
||||
|
||||
class UnwindBuilder
|
||||
{
|
||||
public:
|
||||
enum Arch
|
||||
{
|
||||
X64,
|
||||
A64
|
||||
};
|
||||
|
||||
virtual ~UnwindBuilder() = default;
|
||||
|
||||
virtual void setBeginOffset(size_t beginOffset) = 0;
|
||||
virtual size_t getBeginOffset() const = 0;
|
||||
|
||||
virtual void startInfo(Arch arch) = 0;
|
||||
virtual void startFunction() = 0;
|
||||
virtual void finishFunction(uint32_t beginOffset, uint32_t endOffset) = 0;
|
||||
virtual void finishInfo() = 0;
|
||||
|
||||
// A64-specific; prologue must look like this:
|
||||
// sub sp, sp, stackSize
|
||||
// store sequence that saves regs to [sp..sp+regs.size*8) in the order specified in regs; regs should start with x29, x30 (fp, lr)
|
||||
// mov x29, sp
|
||||
virtual void prologueA64(uint32_t prologueSize, uint32_t stackSize, std::initializer_list<A64::RegisterA64> regs) = 0;
|
||||
|
||||
// X64-specific; prologue must look like this:
|
||||
// optional, indicated by setupFrame:
|
||||
// push rbp
|
||||
// mov rbp, rsp
|
||||
// push reg in the order specified in regs
|
||||
// sub rsp, stackSize
|
||||
virtual void prologueX64(uint32_t prologueSize, uint32_t stackSize, bool setupFrame, std::initializer_list<X64::RegisterX64> gpr,
|
||||
const std::vector<X64::RegisterX64>& simd) = 0;
|
||||
|
||||
virtual size_t getSize() const = 0;
|
||||
virtual size_t getFunctionCount() const = 0;
|
||||
|
||||
// This will place the unwinding data at the target address and might update values of some fields
|
||||
virtual void finalize(char* target, size_t offset, void* funcAddress, size_t funcSize) const = 0;
|
||||
};
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
55
external/luau/include/Luau/UnwindBuilderDwarf2.h
vendored
Normal file
55
external/luau/include/Luau/UnwindBuilderDwarf2.h
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/RegisterX64.h"
|
||||
#include "UnwindBuilder.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
struct UnwindFunctionDwarf2
|
||||
{
|
||||
uint32_t beginOffset;
|
||||
uint32_t endOffset;
|
||||
uint32_t fdeEntryStartPos;
|
||||
};
|
||||
|
||||
class UnwindBuilderDwarf2 : public UnwindBuilder
|
||||
{
|
||||
public:
|
||||
void setBeginOffset(size_t beginOffset) override;
|
||||
size_t getBeginOffset() const override;
|
||||
|
||||
void startInfo(Arch arch) override;
|
||||
void startFunction() override;
|
||||
void finishFunction(uint32_t beginOffset, uint32_t endOffset) override;
|
||||
void finishInfo() override;
|
||||
|
||||
void prologueA64(uint32_t prologueSize, uint32_t stackSize, std::initializer_list<A64::RegisterA64> regs) override;
|
||||
void prologueX64(uint32_t prologueSize, uint32_t stackSize, bool setupFrame, std::initializer_list<X64::RegisterX64> gpr,
|
||||
const std::vector<X64::RegisterX64>& simd) override;
|
||||
|
||||
size_t getSize() const override;
|
||||
size_t getFunctionCount() const override;
|
||||
|
||||
void finalize(char* target, size_t offset, void* funcAddress, size_t funcSize) const override;
|
||||
|
||||
private:
|
||||
size_t beginOffset = 0;
|
||||
|
||||
std::vector<UnwindFunctionDwarf2> unwindFunctions;
|
||||
|
||||
static const unsigned kRawDataLimit = 1024;
|
||||
uint8_t rawData[kRawDataLimit];
|
||||
uint8_t* pos = rawData;
|
||||
|
||||
// We will remember the FDE location to write some of the fields like entry length, function start and size later
|
||||
uint8_t* fdeEntryStart = nullptr;
|
||||
};
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
79
external/luau/include/Luau/UnwindBuilderWin.h
vendored
Normal file
79
external/luau/include/Luau/UnwindBuilderWin.h
vendored
Normal file
|
@ -0,0 +1,79 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "Luau/RegisterX64.h"
|
||||
#include "UnwindBuilder.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Luau
|
||||
{
|
||||
namespace CodeGen
|
||||
{
|
||||
|
||||
// This struct matches the layout of x64 RUNTIME_FUNCTION from winnt.h
|
||||
struct UnwindFunctionWin
|
||||
{
|
||||
uint32_t beginOffset;
|
||||
uint32_t endOffset;
|
||||
uint32_t unwindInfoOffset;
|
||||
};
|
||||
|
||||
// This struct matches the layout of x64 UNWIND_INFO from ehdata.h
|
||||
struct UnwindInfoWin
|
||||
{
|
||||
uint8_t version : 3;
|
||||
uint8_t flags : 5;
|
||||
uint8_t prologsize;
|
||||
uint8_t unwindcodecount;
|
||||
uint8_t framereg : 4;
|
||||
uint8_t frameregoff : 4;
|
||||
};
|
||||
|
||||
// This struct matches the layout of UNWIND_CODE from ehdata.h
|
||||
struct UnwindCodeWin
|
||||
{
|
||||
uint8_t offset;
|
||||
uint8_t opcode : 4;
|
||||
uint8_t opinfo : 4;
|
||||
};
|
||||
|
||||
class UnwindBuilderWin : public UnwindBuilder
|
||||
{
|
||||
public:
|
||||
void setBeginOffset(size_t beginOffset) override;
|
||||
size_t getBeginOffset() const override;
|
||||
|
||||
void startInfo(Arch arch) override;
|
||||
void startFunction() override;
|
||||
void finishFunction(uint32_t beginOffset, uint32_t endOffset) override;
|
||||
void finishInfo() override;
|
||||
|
||||
void prologueA64(uint32_t prologueSize, uint32_t stackSize, std::initializer_list<A64::RegisterA64> regs) override;
|
||||
void prologueX64(uint32_t prologueSize, uint32_t stackSize, bool setupFrame, std::initializer_list<X64::RegisterX64> gpr,
|
||||
const std::vector<X64::RegisterX64>& simd) override;
|
||||
|
||||
size_t getSize() const override;
|
||||
size_t getFunctionCount() const override;
|
||||
|
||||
void finalize(char* target, size_t offset, void* funcAddress, size_t funcSize) const override;
|
||||
|
||||
private:
|
||||
size_t beginOffset = 0;
|
||||
|
||||
static const unsigned kRawDataLimit = 1024;
|
||||
uint8_t rawData[kRawDataLimit];
|
||||
uint8_t* rawDataPos = rawData;
|
||||
|
||||
std::vector<UnwindFunctionWin> unwindFunctions;
|
||||
|
||||
// Windows unwind codes are written in reverse, so we have to collect them all first
|
||||
std::vector<UnwindCodeWin> unwindCodes;
|
||||
|
||||
uint8_t prologSize = 0;
|
||||
X64::RegisterX64 frameReg = X64::noreg;
|
||||
uint8_t frameRegOffset = 0;
|
||||
};
|
||||
|
||||
} // namespace CodeGen
|
||||
} // namespace Luau
|
467
external/luau/include/lua.h
vendored
Normal file
467
external/luau/include/lua.h
vendored
Normal file
|
@ -0,0 +1,467 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "luaconf.h"
|
||||
|
||||
|
||||
|
||||
|
||||
// option for multiple returns in `lua_pcall' and `lua_call'
|
||||
#define LUA_MULTRET (-1)
|
||||
|
||||
/*
|
||||
** pseudo-indices
|
||||
*/
|
||||
#define LUA_REGISTRYINDEX (-LUAI_MAXCSTACK - 2000)
|
||||
#define LUA_ENVIRONINDEX (-LUAI_MAXCSTACK - 2001)
|
||||
#define LUA_GLOBALSINDEX (-LUAI_MAXCSTACK - 2002)
|
||||
#define lua_upvalueindex(i) (LUA_GLOBALSINDEX - (i))
|
||||
#define lua_ispseudo(i) ((i) <= LUA_REGISTRYINDEX)
|
||||
|
||||
// thread status; 0 is OK
|
||||
enum lua_Status
|
||||
{
|
||||
LUA_OK = 0,
|
||||
LUA_YIELD,
|
||||
LUA_ERRRUN,
|
||||
LUA_ERRSYNTAX, // legacy error code, preserved for compatibility
|
||||
LUA_ERRMEM,
|
||||
LUA_ERRERR,
|
||||
LUA_BREAK, // yielded for a debug breakpoint
|
||||
};
|
||||
|
||||
enum lua_CoStatus
|
||||
{
|
||||
LUA_CORUN = 0, // running
|
||||
LUA_COSUS, // suspended
|
||||
LUA_CONOR, // 'normal' (it resumed another coroutine)
|
||||
LUA_COFIN, // finished
|
||||
LUA_COERR, // finished with error
|
||||
};
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
typedef int (*lua_CFunction)(lua_State* L);
|
||||
typedef int (*lua_Continuation)(lua_State* L, int status);
|
||||
|
||||
/*
|
||||
** prototype for memory-allocation functions
|
||||
*/
|
||||
|
||||
typedef void* (*lua_Alloc)(void* ud, void* ptr, size_t osize, size_t nsize);
|
||||
|
||||
// non-return type
|
||||
#define l_noret void LUA_NORETURN
|
||||
|
||||
/*
|
||||
** basic types
|
||||
*/
|
||||
#define LUA_TNONE (-1)
|
||||
|
||||
/*
|
||||
* WARNING: if you change the order of this enumeration,
|
||||
* grep "ORDER TYPE"
|
||||
*/
|
||||
// clang-format off
|
||||
enum lua_Type
|
||||
{
|
||||
LUA_TNIL = 0, // must be 0 due to lua_isnoneornil
|
||||
LUA_TBOOLEAN = 1, // must be 1 due to l_isfalse
|
||||
|
||||
|
||||
LUA_TLIGHTUSERDATA,
|
||||
LUA_TNUMBER,
|
||||
LUA_TVECTOR,
|
||||
|
||||
LUA_TSTRING, // all types above this must be value types, all types below this must be GC types - see iscollectable
|
||||
|
||||
|
||||
LUA_TTABLE,
|
||||
LUA_TFUNCTION,
|
||||
LUA_TUSERDATA,
|
||||
LUA_TTHREAD,
|
||||
|
||||
// values below this line are used in GCObject tags but may never show up in TValue type tags
|
||||
LUA_TPROTO,
|
||||
LUA_TUPVAL,
|
||||
LUA_TDEADKEY,
|
||||
|
||||
// the count of TValue type tags
|
||||
LUA_T_COUNT = LUA_TPROTO
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
// type of numbers in Luau
|
||||
typedef double lua_Number;
|
||||
|
||||
// type for integer functions
|
||||
typedef int lua_Integer;
|
||||
|
||||
// unsigned integer type
|
||||
typedef unsigned lua_Unsigned;
|
||||
|
||||
/*
|
||||
** 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 lua_State* lua_mainthread(lua_State* L);
|
||||
LUA_API void lua_resetthread(lua_State* L);
|
||||
LUA_API int lua_isthreadreset(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_remove(lua_State* L, int idx);
|
||||
LUA_API void lua_insert(lua_State* L, int idx);
|
||||
LUA_API void lua_replace(lua_State* L, int idx);
|
||||
LUA_API int lua_checkstack(lua_State* L, int sz);
|
||||
LUA_API void lua_rawcheckstack(lua_State* L, int sz); // allows for unlimited stack frames
|
||||
|
||||
LUA_API void lua_xmove(lua_State* from, lua_State* to, int n);
|
||||
LUA_API void lua_xpush(lua_State* from, lua_State* to, int idx);
|
||||
|
||||
/*
|
||||
** 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_isLfunction(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 int lua_equal(lua_State* L, int idx1, int idx2);
|
||||
LUA_API int lua_rawequal(lua_State* L, int idx1, int idx2);
|
||||
LUA_API int lua_lessthan(lua_State* L, int idx1, int idx2);
|
||||
|
||||
LUA_API double lua_tonumberx(lua_State* L, int idx, int* isnum);
|
||||
LUA_API int lua_tointegerx(lua_State* L, int idx, int* isnum);
|
||||
LUA_API unsigned lua_tounsignedx(lua_State* L, int idx, int* isnum);
|
||||
LUA_API const float* lua_tovector(lua_State* L, int idx);
|
||||
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 const char* lua_tostringatom(lua_State* L, int idx, int* atom);
|
||||
LUA_API const char* lua_namecallatom(lua_State* L, int* atom);
|
||||
LUA_API int lua_objlen(lua_State* L, int idx);
|
||||
LUA_API lua_CFunction lua_tocfunction(lua_State* L, int idx);
|
||||
LUA_API void* lua_tolightuserdata(lua_State* L, int idx);
|
||||
LUA_API void* lua_touserdata(lua_State* L, int idx);
|
||||
LUA_API void* lua_touserdatatagged(lua_State* L, int idx, int tag);
|
||||
LUA_API int lua_userdatatag(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);
|
||||
|
||||
/*
|
||||
** push functions (C -> stack)
|
||||
*/
|
||||
LUA_API void lua_pushnil(lua_State* L);
|
||||
LUA_API void lua_pushnumber(lua_State* L, double n);
|
||||
LUA_API void lua_pushinteger(lua_State* L, int n);
|
||||
LUA_API void lua_pushunsigned(lua_State* L, unsigned n);
|
||||
#if LUA_VECTOR_SIZE == 4
|
||||
LUA_API void lua_pushvector(lua_State* L, float x, float y, float z, float w);
|
||||
#else
|
||||
LUA_API void lua_pushvector(lua_State* L, float x, float y, float z);
|
||||
#endif
|
||||
LUA_API void lua_pushlstring(lua_State* L, const char* s, size_t l);
|
||||
LUA_API void 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 LUA_PRINTF_ATTR(2, 3) const char* lua_pushfstringL(lua_State* L, const char* fmt, ...);
|
||||
LUA_API void lua_pushcclosurek(lua_State* L, lua_CFunction fn, const char* debugname, int nup, lua_Continuation cont);
|
||||
LUA_API void lua_pushboolean(lua_State* L, int b);
|
||||
LUA_API int lua_pushthread(lua_State* L);
|
||||
|
||||
LUA_API void lua_pushlightuserdata(lua_State* L, void* p);
|
||||
LUA_API void* lua_newuserdatatagged(lua_State* L, size_t sz, int tag);
|
||||
LUA_API void* lua_newuserdatadtor(lua_State* L, size_t sz, void (*dtor)(void*));
|
||||
|
||||
/*
|
||||
** get functions (Lua -> stack)
|
||||
*/
|
||||
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_rawgetfield(lua_State* L, int idx, const char* k);
|
||||
LUA_API int lua_rawget(lua_State* L, int idx);
|
||||
LUA_API int lua_rawgeti(lua_State* L, int idx, int n);
|
||||
LUA_API void lua_createtable(lua_State* L, int narr, int nrec);
|
||||
|
||||
LUA_API void lua_setreadonly(lua_State* L, int idx, int enabled);
|
||||
LUA_API int lua_getreadonly(lua_State* L, int idx);
|
||||
LUA_API void lua_setsafeenv(lua_State* L, int idx, int enabled);
|
||||
|
||||
LUA_API int lua_getmetatable(lua_State* L, int objindex);
|
||||
LUA_API void lua_getfenv(lua_State* L, int idx);
|
||||
|
||||
/*
|
||||
** set functions (stack -> Lua)
|
||||
*/
|
||||
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_rawsetfield(lua_State* L, int idx, const char* k);
|
||||
LUA_API void lua_rawset(lua_State* L, int idx);
|
||||
LUA_API void lua_rawseti(lua_State* L, int idx, int n);
|
||||
LUA_API int lua_setmetatable(lua_State* L, int objindex);
|
||||
LUA_API int lua_setfenv(lua_State* L, int idx);
|
||||
|
||||
/*
|
||||
** `load' and `call' functions (load and run Luau bytecode)
|
||||
*/
|
||||
LUA_API int luau_load(lua_State* L, const char* chunkname, const char* data, size_t size, int env);
|
||||
LUA_API void lua_call(lua_State* L, int nargs, int nresults);
|
||||
LUA_API int lua_pcall(lua_State* L, int nargs, int nresults, int errfunc);
|
||||
|
||||
/*
|
||||
** coroutine functions
|
||||
*/
|
||||
LUA_API int lua_yield(lua_State* L, int nresults);
|
||||
LUA_API int lua_break(lua_State* L);
|
||||
LUA_API int lua_resume(lua_State* L, lua_State* from, int narg);
|
||||
LUA_API int lua_resumeerror(lua_State* L, lua_State* from);
|
||||
LUA_API int lua_status(lua_State* L);
|
||||
LUA_API int lua_isyieldable(lua_State* L);
|
||||
LUA_API void* lua_getthreaddata(lua_State* L);
|
||||
LUA_API void lua_setthreaddata(lua_State* L, void* data);
|
||||
LUA_API int lua_costatus(lua_State* L, lua_State* co);
|
||||
|
||||
/*
|
||||
** garbage-collection function and options
|
||||
*/
|
||||
|
||||
enum lua_GCOp
|
||||
{
|
||||
// stop and resume incremental garbage collection
|
||||
LUA_GCSTOP,
|
||||
LUA_GCRESTART,
|
||||
|
||||
// run a full GC cycle; not recommended for latency sensitive applications
|
||||
LUA_GCCOLLECT,
|
||||
|
||||
// return the heap size in KB and the remainder in bytes
|
||||
LUA_GCCOUNT,
|
||||
LUA_GCCOUNTB,
|
||||
|
||||
// return 1 if GC is active (not stopped); note that GC may not be actively collecting even if it's running
|
||||
LUA_GCISRUNNING,
|
||||
|
||||
/*
|
||||
** perform an explicit GC step, with the step size specified in KB
|
||||
**
|
||||
** garbage collection is handled by 'assists' that perform some amount of GC work matching pace of allocation
|
||||
** explicit GC steps allow to perform some amount of work at custom points to offset the need for GC assists
|
||||
** note that GC might also be paused for some duration (until bytes allocated meet the threshold)
|
||||
** if an explicit step is performed during this pause, it will trigger the start of the next collection cycle
|
||||
*/
|
||||
LUA_GCSTEP,
|
||||
|
||||
/*
|
||||
** tune GC parameters G (goal), S (step multiplier) and step size (usually best left ignored)
|
||||
**
|
||||
** garbage collection is incremental and tries to maintain the heap size to balance memory and performance overhead
|
||||
** this overhead is determined by G (goal) which is the ratio between total heap size and the amount of live data in it
|
||||
** G is specified in percentages; by default G=200% which means that the heap is allowed to grow to ~2x the size of live data.
|
||||
**
|
||||
** collector tries to collect S% of allocated bytes by interrupting the application after step size bytes were allocated.
|
||||
** when S is too small, collector may not be able to catch up and the effective goal that can be reached will be larger.
|
||||
** S is specified in percentages; by default S=200% which means that collector will run at ~2x the pace of allocations.
|
||||
**
|
||||
** it is recommended to set S in the interval [100 / (G - 100), 100 + 100 / (G - 100))] with a minimum value of 150%; for example:
|
||||
** - for G=200%, S should be in the interval [150%, 200%]
|
||||
** - for G=150%, S should be in the interval [200%, 300%]
|
||||
** - for G=125%, S should be in the interval [400%, 500%]
|
||||
*/
|
||||
LUA_GCSETGOAL,
|
||||
LUA_GCSETSTEPMUL,
|
||||
LUA_GCSETSTEPSIZE,
|
||||
};
|
||||
|
||||
LUA_API int lua_gc(lua_State* L, int what, int data);
|
||||
|
||||
/*
|
||||
** memory statistics
|
||||
** all allocated bytes are attributed to the memory category of the running thread (0..LUA_MEMORY_CATEGORIES-1)
|
||||
*/
|
||||
|
||||
LUA_API void lua_setmemcat(lua_State* L, int category);
|
||||
LUA_API size_t lua_totalbytes(lua_State* L, int category);
|
||||
|
||||
/*
|
||||
** miscellaneous functions
|
||||
*/
|
||||
|
||||
LUA_API l_noret lua_error(lua_State* L);
|
||||
|
||||
LUA_API int lua_next(lua_State* L, int idx);
|
||||
LUA_API int lua_rawiter(lua_State* L, int idx, int iter);
|
||||
|
||||
LUA_API void lua_concat(lua_State* L, int n);
|
||||
|
||||
LUA_API uintptr_t lua_encodepointer(lua_State* L, uintptr_t p);
|
||||
|
||||
LUA_API double lua_clock();
|
||||
|
||||
LUA_API void lua_setuserdatatag(lua_State* L, int idx, int tag);
|
||||
|
||||
typedef void (*lua_Destructor)(lua_State* L, void* userdata);
|
||||
|
||||
LUA_API void lua_setuserdatadtor(lua_State* L, int tag, lua_Destructor dtor);
|
||||
LUA_API lua_Destructor lua_getuserdatadtor(lua_State* L, int tag);
|
||||
|
||||
LUA_API void lua_clonefunction(lua_State* L, int idx);
|
||||
|
||||
LUA_API void lua_cleartable(lua_State* L, int idx);
|
||||
|
||||
/*
|
||||
** reference system, can be used to pin objects
|
||||
*/
|
||||
#define LUA_NOREF -1
|
||||
#define LUA_REFNIL 0
|
||||
|
||||
LUA_API int lua_ref(lua_State* L, int idx);
|
||||
LUA_API void lua_unref(lua_State* L, int ref);
|
||||
|
||||
#define lua_getref(L, ref) lua_rawgeti(L, LUA_REGISTRYINDEX, (ref))
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
#define lua_tonumber(L, i) lua_tonumberx(L, i, NULL)
|
||||
#define lua_tointeger(L, i) lua_tointegerx(L, i, NULL)
|
||||
#define lua_tounsigned(L, i) lua_tounsignedx(L, i, NULL)
|
||||
|
||||
#define lua_pop(L, n) lua_settop(L, -(n)-1)
|
||||
|
||||
#define lua_newtable(L) lua_createtable(L, 0, 0)
|
||||
#define lua_newuserdata(L, s) lua_newuserdatatagged(L, s, 0)
|
||||
|
||||
#define lua_strlen(L, i) lua_objlen(L, (i))
|
||||
|
||||
#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_isvector(L, n) (lua_type(L, (n)) == LUA_TVECTOR)
|
||||
#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)) <= LUA_TNIL)
|
||||
|
||||
#define lua_pushliteral(L, s) lua_pushlstring(L, "" s, (sizeof(s) / sizeof(char)) - 1)
|
||||
#define lua_pushcfunction(L, fn, debugname) lua_pushcclosurek(L, fn, debugname, 0, NULL)
|
||||
#define lua_pushcclosure(L, fn, debugname, nup) lua_pushcclosurek(L, fn, debugname, nup, NULL)
|
||||
|
||||
#define lua_setglobal(L, s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
|
||||
#define lua_getglobal(L, s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
|
||||
|
||||
#define lua_tostring(L, i) lua_tolstring(L, (i), NULL)
|
||||
|
||||
#define lua_pushfstring(L, fmt, ...) lua_pushfstringL(L, fmt, ##__VA_ARGS__)
|
||||
|
||||
/*
|
||||
** {======================================================================
|
||||
** Debug API
|
||||
** =======================================================================
|
||||
*/
|
||||
|
||||
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_stackdepth(lua_State* L);
|
||||
LUA_API int lua_getinfo(lua_State* L, int level, const char* what, lua_Debug* ar);
|
||||
LUA_API int lua_getargument(lua_State* L, int level, int n);
|
||||
LUA_API const char* lua_getlocal(lua_State* L, int level, int n);
|
||||
LUA_API const char* lua_setlocal(lua_State* L, int level, 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_singlestep(lua_State* L, int enabled);
|
||||
LUA_API int lua_breakpoint(lua_State* L, int funcindex, int line, int enabled);
|
||||
|
||||
typedef void (*lua_Coverage)(void* context, const char* function, int linedefined, int depth, const int* hits, size_t size);
|
||||
|
||||
LUA_API void lua_getcoverage(lua_State* L, int funcindex, void* context, lua_Coverage callback);
|
||||
|
||||
// Warning: this function is not thread-safe since it stores the result in a shared global array! Only use for debugging.
|
||||
LUA_API const char* lua_debugtrace(lua_State* L);
|
||||
|
||||
struct lua_Debug
|
||||
{
|
||||
const char* name; // (n)
|
||||
const char* what; // (s) `Lua', `C', `main', `tail'
|
||||
const char* source; // (s)
|
||||
const char* short_src; // (s)
|
||||
int linedefined; // (s)
|
||||
int currentline; // (l)
|
||||
unsigned char nupvals; // (u) number of upvalues
|
||||
unsigned char nparams; // (a) number of parameters
|
||||
char isvararg; // (a)
|
||||
void* userdata; // only valid in luau_callhook
|
||||
|
||||
char ssbuf[LUA_IDSIZE];
|
||||
};
|
||||
|
||||
// }======================================================================
|
||||
|
||||
/* Callbacks that can be used to reconfigure behavior of the VM dynamically.
|
||||
* These are shared between all coroutines.
|
||||
*
|
||||
* Note: interrupt is safe to set from an arbitrary thread but all other callbacks
|
||||
* can only be changed when the VM is not running any code */
|
||||
struct lua_Callbacks
|
||||
{
|
||||
void* userdata; // arbitrary userdata pointer that is never overwritten by Luau
|
||||
|
||||
void (*interrupt)(lua_State* L, int gc); // gets called at safepoints (loop back edges, call/ret, gc) if set
|
||||
void (*panic)(lua_State* L, int errcode); // gets called when an unprotected error is raised (if longjmp is used)
|
||||
|
||||
void (*userthread)(lua_State* LP, lua_State* L); // gets called when L is created (LP == parent) or destroyed (LP == NULL)
|
||||
int16_t (*useratom)(const char* s, size_t l); // gets called when a string is created; returned atom can be retrieved via tostringatom
|
||||
|
||||
void (*debugbreak)(lua_State* L, lua_Debug* ar); // gets called when BREAK instruction is encountered
|
||||
void (*debugstep)(lua_State* L, lua_Debug* ar); // gets called after each instruction in single step mode
|
||||
void (*debuginterrupt)(lua_State* L, lua_Debug* ar); // gets called when thread execution is interrupted by break in another thread
|
||||
void (*debugprotectederror)(lua_State* L); // gets called when protected call results in an error
|
||||
};
|
||||
typedef struct lua_Callbacks lua_Callbacks;
|
||||
|
||||
LUA_API lua_Callbacks* lua_callbacks(lua_State* L);
|
||||
|
||||
/******************************************************************************
|
||||
* Copyright (c) 2019-2023 Roblox Corporation
|
||||
* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
|
||||
*
|
||||
* 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.
|
||||
******************************************************************************/
|
42
external/luau/include/luacode.h
vendored
Normal file
42
external/luau/include/luacode.h
vendored
Normal file
|
@ -0,0 +1,42 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
// Can be used to reconfigure visibility/exports for public APIs
|
||||
#ifndef LUACODE_API
|
||||
#define LUACODE_API extern
|
||||
#endif
|
||||
|
||||
typedef struct lua_CompileOptions lua_CompileOptions;
|
||||
|
||||
struct lua_CompileOptions
|
||||
{
|
||||
// 0 - no optimization
|
||||
// 1 - baseline optimization level that doesn't prevent debuggability
|
||||
// 2 - includes optimizations that harm debuggability such as inlining
|
||||
int optimizationLevel; // default=1
|
||||
|
||||
// 0 - no debugging support
|
||||
// 1 - line info & function names only; sufficient for backtraces
|
||||
// 2 - full debug info with local & upvalue names; necessary for debugger
|
||||
int debugLevel; // default=1
|
||||
|
||||
// 0 - no code coverage support
|
||||
// 1 - statement coverage
|
||||
// 2 - statement and expression coverage (verbose)
|
||||
int coverageLevel; // default=0
|
||||
|
||||
// global builtin to construct vectors; disabled by default
|
||||
const char* vectorLib;
|
||||
const char* vectorCtor;
|
||||
|
||||
// vector type name for type tables; disabled by default
|
||||
const char* vectorType;
|
||||
|
||||
// null-terminated array of globals that are mutable; disables the import optimization for fields accessed through these
|
||||
const char* const* mutableGlobals;
|
||||
};
|
||||
|
||||
// compile source to bytecode; when source compilation fails, the resulting bytecode contains the encoded error. use free() to destroy
|
||||
LUACODE_API char* luau_compile(const char* source, size_t size, lua_CompileOptions* options, size_t* outsize);
|
18
external/luau/include/luacodegen.h
vendored
Normal file
18
external/luau/include/luacodegen.h
vendored
Normal file
|
@ -0,0 +1,18 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
// Can be used to reconfigure visibility/exports for public APIs
|
||||
#ifndef LUACODEGEN_API
|
||||
#define LUACODEGEN_API extern
|
||||
#endif
|
||||
|
||||
typedef struct lua_State lua_State;
|
||||
|
||||
// returns 1 if Luau code generator is supported, 0 otherwise
|
||||
LUACODEGEN_API int luau_codegen_supported(void);
|
||||
|
||||
// create an instance of Luau code generator. you must check that this feature is supported using luau_codegen_supported().
|
||||
LUACODEGEN_API void luau_codegen_create(lua_State* L);
|
||||
|
||||
// build target function and all inner functions
|
||||
LUACODEGEN_API void luau_codegen_compile(lua_State* L, int idx);
|
145
external/luau/include/luaconf.h
vendored
Normal file
145
external/luau/include/luaconf.h
vendored
Normal file
|
@ -0,0 +1,145 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
// When debugging complex issues, consider enabling one of these:
|
||||
// This will reallocate the stack very aggressively at every opportunity; use this with asan to catch stale stack pointers
|
||||
// #define HARDSTACKTESTS 1
|
||||
// This will call GC validation very aggressively at every incremental GC step; use this with caution as it's SLOW
|
||||
// #define HARDMEMTESTS 1
|
||||
// This will call GC validation very aggressively at every GC opportunity; use this with caution as it's VERY SLOW
|
||||
// #define HARDMEMTESTS 2
|
||||
|
||||
// To force MSVC2017+ to generate SSE2 code for some stdlib functions we need to locally enable /fp:fast
|
||||
// Note that /fp:fast changes the semantics of floating point comparisons so this is only safe to do for functions without ones
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define LUAU_FASTMATH_BEGIN __pragma(float_control(precise, off, push))
|
||||
#define LUAU_FASTMATH_END __pragma(float_control(pop))
|
||||
#else
|
||||
#define LUAU_FASTMATH_BEGIN
|
||||
#define LUAU_FASTMATH_END
|
||||
#endif
|
||||
|
||||
// Some functions like floor/ceil have SSE4.1 equivalents but we currently support systems without SSE4.1
|
||||
// Note that we only need to do this when SSE4.1 support is not guaranteed by compiler settings, as otherwise compiler will optimize these for us.
|
||||
#if (defined(__x86_64__) || defined(_M_X64)) && !defined(__SSE4_1__) && !defined(__AVX__)
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#define LUAU_TARGET_SSE41
|
||||
#elif defined(__GNUC__) && defined(__has_attribute)
|
||||
#if __has_attribute(target)
|
||||
#define LUAU_TARGET_SSE41 __attribute__((target("sse4.1")))
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Used on functions that have a printf-like interface to validate them statically
|
||||
#if defined(__GNUC__)
|
||||
#define LUA_PRINTF_ATTR(fmt, arg) __attribute__((format(printf, fmt, arg)))
|
||||
#else
|
||||
#define LUA_PRINTF_ATTR(fmt, arg)
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define LUA_NORETURN __declspec(noreturn)
|
||||
#else
|
||||
#define LUA_NORETURN __attribute__((__noreturn__))
|
||||
#endif
|
||||
|
||||
// Can be used to reconfigure visibility/exports for public APIs
|
||||
#ifndef LUA_API
|
||||
#define LUA_API extern
|
||||
#endif
|
||||
|
||||
#define LUALIB_API LUA_API
|
||||
|
||||
// Can be used to reconfigure visibility for internal APIs
|
||||
#if defined(__GNUC__)
|
||||
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
|
||||
#define LUAI_DATA LUAI_FUNC
|
||||
#else
|
||||
#define LUAI_FUNC extern
|
||||
#define LUAI_DATA extern
|
||||
#endif
|
||||
|
||||
// Can be used to reconfigure internal error handling to use longjmp instead of C++ EH
|
||||
#ifndef LUA_USE_LONGJMP
|
||||
#define LUA_USE_LONGJMP 0
|
||||
#endif
|
||||
|
||||
// LUA_IDSIZE gives the maximum size for the description of the source
|
||||
#ifndef LUA_IDSIZE
|
||||
#define LUA_IDSIZE 256
|
||||
#endif
|
||||
|
||||
// LUA_MINSTACK is the guaranteed number of Lua stack slots available to a C function
|
||||
#ifndef LUA_MINSTACK
|
||||
#define LUA_MINSTACK 20
|
||||
#endif
|
||||
|
||||
// LUAI_MAXCSTACK limits the number of Lua stack slots that a C function can use
|
||||
#ifndef LUAI_MAXCSTACK
|
||||
#define LUAI_MAXCSTACK 8000
|
||||
#endif
|
||||
|
||||
// LUAI_MAXCALLS limits the number of nested calls
|
||||
#ifndef LUAI_MAXCALLS
|
||||
#define LUAI_MAXCALLS 20000
|
||||
#endif
|
||||
|
||||
// LUAI_MAXCCALLS is the maximum depth for nested C calls; this limit depends on native stack size
|
||||
#ifndef LUAI_MAXCCALLS
|
||||
#define LUAI_MAXCCALLS 200
|
||||
#endif
|
||||
|
||||
// buffer size used for on-stack string operations; this limit depends on native stack size
|
||||
#ifndef LUA_BUFFERSIZE
|
||||
#define LUA_BUFFERSIZE 512
|
||||
#endif
|
||||
|
||||
// number of valid Lua userdata tags
|
||||
#ifndef LUA_UTAG_LIMIT
|
||||
#define LUA_UTAG_LIMIT 128
|
||||
#endif
|
||||
|
||||
// upper bound for number of size classes used by page allocator
|
||||
#ifndef LUA_SIZECLASSES
|
||||
#define LUA_SIZECLASSES 32
|
||||
#endif
|
||||
|
||||
// available number of separate memory categories
|
||||
#ifndef LUA_MEMORY_CATEGORIES
|
||||
#define LUA_MEMORY_CATEGORIES 256
|
||||
#endif
|
||||
|
||||
// minimum size for the string table (must be power of 2)
|
||||
#ifndef LUA_MINSTRTABSIZE
|
||||
#define LUA_MINSTRTABSIZE 32
|
||||
#endif
|
||||
|
||||
// maximum number of captures supported by pattern matching
|
||||
#ifndef LUA_MAXCAPTURES
|
||||
#define LUA_MAXCAPTURES 32
|
||||
#endif
|
||||
|
||||
// }==================================================================
|
||||
|
||||
/*
|
||||
@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
|
||||
** CHANGE it if your system requires alignments larger than double. (For
|
||||
** instance, if your system supports long doubles and they must be
|
||||
** aligned in 16-byte boundaries, then you should add long double in the
|
||||
** union.) Probably you do not need to change this.
|
||||
*/
|
||||
#define LUAI_USER_ALIGNMENT_T \
|
||||
union \
|
||||
{ \
|
||||
double u; \
|
||||
void* s; \
|
||||
long l; \
|
||||
}
|
||||
|
||||
#ifndef LUA_VECTOR_SIZE
|
||||
#define LUA_VECTOR_SIZE 3 // must be 3 or 4
|
||||
#endif
|
||||
|
||||
#define LUA_EXTRA_SIZE (LUA_VECTOR_SIZE - 2)
|
138
external/luau/include/lualib.h
vendored
Normal file
138
external/luau/include/lualib.h
vendored
Normal file
|
@ -0,0 +1,138 @@
|
|||
// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details
|
||||
// This code is based on Lua 5.x implementation licensed under MIT License; see lua_LICENSE.txt for details
|
||||
#pragma once
|
||||
|
||||
#include "lua.h"
|
||||
|
||||
#define luaL_error(L, fmt, ...) luaL_errorL(L, fmt, ##__VA_ARGS__)
|
||||
#define luaL_typeerror(L, narg, tname) luaL_typeerrorL(L, narg, tname)
|
||||
#define luaL_argerror(L, narg, extramsg) luaL_argerrorL(L, narg, extramsg)
|
||||
|
||||
struct luaL_Reg
|
||||
{
|
||||
const char* name;
|
||||
lua_CFunction func;
|
||||
};
|
||||
typedef struct luaL_Reg luaL_Reg;
|
||||
|
||||
LUALIB_API void luaL_register(lua_State* L, const char* libname, const luaL_Reg* l);
|
||||
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 l_noret luaL_typeerrorL(lua_State* L, int narg, const char* tname);
|
||||
LUALIB_API l_noret luaL_argerrorL(lua_State* L, int narg, const char* extramsg);
|
||||
LUALIB_API const char* luaL_checklstring(lua_State* L, int numArg, size_t* l);
|
||||
LUALIB_API const char* luaL_optlstring(lua_State* L, int numArg, const char* def, size_t* l);
|
||||
LUALIB_API double luaL_checknumber(lua_State* L, int numArg);
|
||||
LUALIB_API double luaL_optnumber(lua_State* L, int nArg, double def);
|
||||
|
||||
LUALIB_API int luaL_checkboolean(lua_State* L, int narg);
|
||||
LUALIB_API int luaL_optboolean(lua_State* L, int narg, int def);
|
||||
|
||||
LUALIB_API int luaL_checkinteger(lua_State* L, int numArg);
|
||||
LUALIB_API int luaL_optinteger(lua_State* L, int nArg, int def);
|
||||
LUALIB_API unsigned luaL_checkunsigned(lua_State* L, int numArg);
|
||||
LUALIB_API unsigned luaL_optunsigned(lua_State* L, int numArg, unsigned def);
|
||||
|
||||
LUALIB_API const float* luaL_checkvector(lua_State* L, int narg);
|
||||
LUALIB_API const float* luaL_optvector(lua_State* L, int narg, const float* def);
|
||||
|
||||
LUALIB_API void luaL_checkstack(lua_State* L, int sz, const char* msg);
|
||||
LUALIB_API void luaL_checktype(lua_State* L, int narg, int t);
|
||||
LUALIB_API void luaL_checkany(lua_State* L, int narg);
|
||||
|
||||
LUALIB_API int luaL_newmetatable(lua_State* L, 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 LUA_PRINTF_ATTR(2, 3) l_noret luaL_errorL(lua_State* L, const char* fmt, ...);
|
||||
|
||||
LUALIB_API int luaL_checkoption(lua_State* L, int narg, const char* def, const char* const lst[]);
|
||||
|
||||
LUALIB_API const char* luaL_tolstring(lua_State* L, int idx, size_t* len);
|
||||
|
||||
LUALIB_API lua_State* luaL_newstate(void);
|
||||
|
||||
LUALIB_API const char* luaL_findtable(lua_State* L, int idx, const char* fname, int szhint);
|
||||
|
||||
LUALIB_API const char* luaL_typename(lua_State* L, int idx);
|
||||
|
||||
/*
|
||||
** ===============================================================
|
||||
** some useful macros
|
||||
** ===============================================================
|
||||
*/
|
||||
|
||||
#define luaL_argcheck(L, cond, arg, extramsg) ((void)((cond) ? (void)0 : luaL_argerror(L, arg, extramsg)))
|
||||
#define luaL_argexpected(L, cond, arg, tname) ((void)((cond) ? (void)0 : 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_getmetatable(L, n) (lua_getfield(L, LUA_REGISTRYINDEX, (n)))
|
||||
|
||||
#define luaL_opt(L, f, n, d) (lua_isnoneornil(L, (n)) ? (d) : f(L, (n)))
|
||||
|
||||
// generic buffer manipulation
|
||||
|
||||
struct luaL_Buffer
|
||||
{
|
||||
char* p; // current position in buffer
|
||||
char* end; // end of the current buffer
|
||||
lua_State* L;
|
||||
struct TString* storage;
|
||||
char buffer[LUA_BUFFERSIZE];
|
||||
};
|
||||
typedef struct luaL_Buffer luaL_Buffer;
|
||||
|
||||
// when internal buffer storage is exhausted, a mutable string value 'storage' will be placed on the stack
|
||||
// in general, functions expect the mutable string buffer to be placed on top of the stack (top-1)
|
||||
// with the exception of luaL_addvalue that expects the value at the top and string buffer further away (top-2)
|
||||
// functions that accept a 'boxloc' support string buffer placement at any location in the stack
|
||||
// all the buffer users we have in Luau match this pattern, but it's something to keep in mind for new uses of buffers
|
||||
|
||||
#define luaL_addchar(B, c) ((void)((B)->p < (B)->end || luaL_extendbuffer(B, 1, -1)), (*(B)->p++ = (char)(c)))
|
||||
#define luaL_addstring(B, s) luaL_addlstring(B, s, strlen(s), -1)
|
||||
|
||||
LUALIB_API void luaL_buffinit(lua_State* L, luaL_Buffer* B);
|
||||
LUALIB_API char* luaL_buffinitsize(lua_State* L, luaL_Buffer* B, size_t size);
|
||||
LUALIB_API char* luaL_extendbuffer(luaL_Buffer* B, size_t additionalsize, int boxloc);
|
||||
LUALIB_API void luaL_reservebuffer(luaL_Buffer* B, size_t size, int boxloc);
|
||||
LUALIB_API void luaL_addlstring(luaL_Buffer* B, const char* s, size_t l, int boxloc);
|
||||
LUALIB_API void luaL_addvalue(luaL_Buffer* B);
|
||||
LUALIB_API void luaL_addvalueany(luaL_Buffer* B, int idx);
|
||||
LUALIB_API void luaL_pushresult(luaL_Buffer* B);
|
||||
LUALIB_API void luaL_pushresultsize(luaL_Buffer* B, size_t size);
|
||||
|
||||
// builtin libraries
|
||||
LUALIB_API int luaopen_base(lua_State* L);
|
||||
|
||||
#define LUA_COLIBNAME "coroutine"
|
||||
LUALIB_API int luaopen_coroutine(lua_State* L);
|
||||
|
||||
#define LUA_TABLIBNAME "table"
|
||||
LUALIB_API int luaopen_table(lua_State* L);
|
||||
|
||||
#define LUA_OSLIBNAME "os"
|
||||
LUALIB_API int luaopen_os(lua_State* L);
|
||||
|
||||
#define LUA_STRLIBNAME "string"
|
||||
LUALIB_API int luaopen_string(lua_State* L);
|
||||
|
||||
#define LUA_BITLIBNAME "bit32"
|
||||
LUALIB_API int luaopen_bit32(lua_State* L);
|
||||
|
||||
#define LUA_UTF8LIBNAME "utf8"
|
||||
LUALIB_API int luaopen_utf8(lua_State* L);
|
||||
|
||||
#define LUA_MATHLIBNAME "math"
|
||||
LUALIB_API int luaopen_math(lua_State* L);
|
||||
|
||||
#define LUA_DBLIBNAME "debug"
|
||||
LUALIB_API int luaopen_debug(lua_State* L);
|
||||
|
||||
// open all builtin libraries
|
||||
LUALIB_API void luaL_openlibs(lua_State* L);
|
||||
|
||||
// sandbox libraries and globals
|
||||
LUALIB_API void luaL_sandbox(lua_State* L);
|
||||
LUALIB_API void luaL_sandboxthread(lua_State* L);
|
BIN
external/luau/lib/win64_vs2017/Luau.Ast.lib
vendored
Normal file
BIN
external/luau/lib/win64_vs2017/Luau.Ast.lib
vendored
Normal file
Binary file not shown.
BIN
external/luau/lib/win64_vs2017/Luau.CodeGen.lib
vendored
Normal file
BIN
external/luau/lib/win64_vs2017/Luau.CodeGen.lib
vendored
Normal file
Binary file not shown.
BIN
external/luau/lib/win64_vs2017/Luau.Compiler.lib
vendored
Normal file
BIN
external/luau/lib/win64_vs2017/Luau.Compiler.lib
vendored
Normal file
Binary file not shown.
BIN
external/luau/lib/win64_vs2017/Luau.Config.lib
vendored
Normal file
BIN
external/luau/lib/win64_vs2017/Luau.Config.lib
vendored
Normal file
Binary file not shown.
BIN
external/luau/lib/win64_vs2017/Luau.VM.lib
vendored
Normal file
BIN
external/luau/lib/win64_vs2017/Luau.VM.lib
vendored
Normal file
Binary file not shown.
|
@ -282,11 +282,15 @@ end
|
|||
|
||||
function useLua()
|
||||
configuration { "vs20*" }
|
||||
linkLib "lua51"
|
||||
libdirs { path.join(ROOT_DIR, "./external/luau/lib/win64_vs2017") }
|
||||
links "Luau.VM"
|
||||
links "Luau.Compiler"
|
||||
links "Luau.CodeGen"
|
||||
links "Luau.Ast"
|
||||
links "Luau.Config"
|
||||
|
||||
configuration {}
|
||||
linkLib "luajit"
|
||||
includedirs { path.join(ROOT_DIR, "./external/luajit/include") }
|
||||
includedirs { path.join(ROOT_DIR, "./external/luau/include") }
|
||||
end
|
||||
|
||||
function libType()
|
||||
|
@ -514,17 +518,15 @@ project "engine"
|
|||
defines { "LZ4_DLL_EXPORT" }
|
||||
end
|
||||
|
||||
includedirs { "../external/luajit/include", "../external/freetype/include" }
|
||||
includedirs { "../external/luau/include", "../external/freetype/include" }
|
||||
|
||||
configuration { "linux" }
|
||||
buildoptions { "`pkg-config --cflags gtk+-3.0`" }
|
||||
|
||||
configuration { "vs20*" }
|
||||
linkLib "lua51"
|
||||
useLua()
|
||||
|
||||
configuration {}
|
||||
|
||||
linkLib "luajit"
|
||||
if _OPTIONS["dynamic-plugins"] then
|
||||
linkLib "freetype"
|
||||
end
|
||||
|
@ -789,7 +791,6 @@ if build_app then
|
|||
linkLib "basisu"
|
||||
end
|
||||
linkLib "freetype"
|
||||
linkLib "luajit"
|
||||
linkLib "recast"
|
||||
|
||||
configuration { "vs*" }
|
||||
|
@ -805,7 +806,7 @@ if build_app then
|
|||
end
|
||||
end
|
||||
|
||||
linkLib "luajit"
|
||||
useLua()
|
||||
linkLib "recast"
|
||||
files { "../src/app/main.cpp" }
|
||||
|
||||
|
@ -962,7 +963,7 @@ if build_studio then
|
|||
linkLib "basisu"
|
||||
end
|
||||
linkLib "freetype"
|
||||
linkLib "luajit"
|
||||
useLua()
|
||||
linkLib "recast"
|
||||
|
||||
if has_plugin("renderer") then
|
||||
|
|
|
@ -87,7 +87,7 @@ bool PropertyAnimation::load(Span<const u8> mem) {
|
|||
lua_State* L = luaL_newstate(); // TODO reuse
|
||||
auto fn = &LuaWrapper::wrapMethodClosure<&PropertyAnimation::LUA_curve>;
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(L, fn, 1);
|
||||
lua_pushcclosure(L, fn, "curve", 1);
|
||||
lua_setglobal(L, "curve");
|
||||
|
||||
return LuaWrapper::execute(L, StringView((const char*)mem.begin(), mem.length()), getPath().c_str(), 0);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "engine/resource.h"
|
||||
#include "engine/resource_manager.h"
|
||||
#include "lz4/lz4.h"
|
||||
#include <luacode.h>
|
||||
|
||||
// use this if you want to be able to use cached resources without having the original
|
||||
// #define CACHE_MASTER
|
||||
|
@ -398,7 +399,11 @@ struct AssetCompilerImpl : AssetCompiler {
|
|||
if (fs.getContentSync(Path(".lumix/resources/_list.txt"), content)) {
|
||||
lua_State* L = luaL_newstate();
|
||||
[&](){
|
||||
if (luaL_loadbuffer(L, (const char*)content.data(), content.size(), "lumix_asset_list") != 0) {
|
||||
size_t bytecodeSize = 0;
|
||||
char* bytecode = luau_compile((const char*)content.data(), content.size(), NULL, &bytecodeSize);
|
||||
int res = luau_load(L, "lumix_asset_list", bytecode, bytecodeSize, 0);
|
||||
free(bytecode);
|
||||
if (res != 0) {
|
||||
logError(list_path, ": ", lua_tostring(L, -1));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2696,7 +2696,7 @@ struct StudioAppImpl final : StudioApp
|
|||
void runScript(const char* src, const char* script_name) override
|
||||
{
|
||||
lua_State* L = m_engine->getState();
|
||||
bool errors = luaL_loadbuffer(L, src, stringLength(src), script_name) != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(L, src, stringLength(src), script_name) != 0;
|
||||
errors = errors || lua_pcall(L, 0, 0, 0) != 0;
|
||||
if (errors)
|
||||
{
|
||||
|
|
|
@ -18,7 +18,8 @@
|
|||
#include "engine/stream.h"
|
||||
#include "engine/string.h"
|
||||
#include "engine/world.h"
|
||||
#include <lua.hpp>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
|
|
|
@ -10,7 +10,8 @@
|
|||
#include "reflection.h"
|
||||
#include "string.h"
|
||||
#include "world.h"
|
||||
#include <lua.hpp>
|
||||
#include <lua.h>
|
||||
#include <luacode.h>
|
||||
|
||||
namespace Lumix {
|
||||
|
||||
|
@ -378,71 +379,13 @@ int SameLine(lua_State* L)
|
|||
|
||||
void registerCFunction(lua_State* L, const char* name, lua_CFunction f)
|
||||
{
|
||||
lua_pushcfunction(L, f);
|
||||
lua_pushcfunction(L, f, name);
|
||||
lua_setfield(L, -2, name);
|
||||
}
|
||||
|
||||
} // namespace LuaImGui
|
||||
|
||||
|
||||
static int LUA_packageLoader(lua_State* L)
|
||||
{
|
||||
const char* module = LuaWrapper::toType<const char*>(L, 1);
|
||||
Path tmp(module);
|
||||
lua_getglobal(L, "LumixAPI");
|
||||
lua_getfield(L, -1, "engine");
|
||||
lua_remove(L, -2);
|
||||
auto* engine = (Engine*)lua_touserdata(L, -1);
|
||||
lua_pop(L, 1);
|
||||
auto& fs = engine->getFileSystem();
|
||||
OutputMemoryStream buf(engine->getAllocator());
|
||||
bool loaded = true;
|
||||
if (!fs.getContentSync(tmp, buf)) {
|
||||
tmp.append(".lua");
|
||||
if (!fs.getContentSync(tmp, buf)) {
|
||||
loaded = false;
|
||||
logError("Failed to open file ", tmp);
|
||||
StaticString<MAX_PATH + 40> msg("Failed to open file ");
|
||||
msg.append(tmp);
|
||||
lua_pushstring(L, msg);
|
||||
}
|
||||
}
|
||||
if (loaded && luaL_loadbuffer(L, (const char*)buf.data(), buf.size(), tmp.c_str()) != 0) {
|
||||
logError("Failed to load package ", tmp, ": ", lua_tostring(L, -1));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
static void installLuaPackageLoader(lua_State* L)
|
||||
{
|
||||
lua_getglobal(L, "package");
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
logError("Lua \"package\" is not a table");
|
||||
return;
|
||||
}
|
||||
lua_getfield(L, -1, "searchers");
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
lua_pop(L, 1);
|
||||
lua_getfield(L, -1, "loaders");
|
||||
if (lua_type(L, -1) != LUA_TTABLE) {
|
||||
logError("Lua \"package.searchers\"/\"package.loaders\" is not a table");
|
||||
return;
|
||||
}
|
||||
}
|
||||
int numLoaders = 0;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, -2) != 0) {
|
||||
lua_pop(L, 1);
|
||||
numLoaders++;
|
||||
}
|
||||
|
||||
lua_pushinteger(L, numLoaders + 1);
|
||||
lua_pushcfunction(L, LUA_packageLoader);
|
||||
lua_rawset(L, -3);
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
|
||||
static Engine* getEngineUpvalue(lua_State* L) {
|
||||
const int index = lua_upvalueindex(1);
|
||||
if (!LuaWrapper::isType<Engine>(L, index)) {
|
||||
|
@ -514,7 +457,7 @@ static int LUA_networkRead(lua_State* L) {
|
|||
char tmp[4096];
|
||||
os::NetworkStream* stream = LuaWrapper::checkArg<os::NetworkStream*>(L, 1);
|
||||
u32 size = LuaWrapper::checkArg<u32>(L, 2);
|
||||
if (size > sizeof(tmp)) return luaL_error(L, "size too big, max %d allowed", sizeof(tmp));
|
||||
if (size > sizeof(tmp)) luaL_error(L, "size too big, max %d allowed", sizeof(tmp));
|
||||
if (!os::read(*stream, tmp, size)) return 0;
|
||||
lua_pushlstring(L, tmp, size);
|
||||
return 1;
|
||||
|
@ -530,7 +473,7 @@ static int LUA_unpackU32(lua_State* L) {
|
|||
size_t size;
|
||||
const char* lstr = lua_tolstring(L, 1, &size);
|
||||
u32 val;
|
||||
if (sizeof(val) != size) return luaL_error(L, "Invalid argument");
|
||||
if (sizeof(val) != size) luaL_error(L, "Invalid argument");
|
||||
|
||||
memcpy(&val, lstr, sizeof(val));
|
||||
lua_pushnumber(L, val);
|
||||
|
@ -666,7 +609,7 @@ static int LUA_loadWorld(lua_State* L)
|
|||
auto* name = LuaWrapper::checkArg<const char*>(L, 2);
|
||||
if (!lua_isfunction(L, 3)) LuaWrapper::argError(L, 3, "function");
|
||||
struct Callback {
|
||||
~Callback() { luaL_unref(L, LUA_REGISTRYINDEX, lua_func); }
|
||||
~Callback() { LuaWrapper::luaL_unref(L, LUA_REGISTRYINDEX, lua_func); }
|
||||
|
||||
void invoke(Span<const u8> mem, bool success) {
|
||||
if (!success) {
|
||||
|
@ -717,11 +660,84 @@ static int LUA_loadWorld(lua_State* L)
|
|||
const Path path("universes/", name, ".unv");
|
||||
inst->path = path;
|
||||
inst->L = L;
|
||||
inst->lua_func = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
inst->lua_func = LuaWrapper::luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
fs.getContent(inst->path, makeDelegate<&Callback::invoke>(inst));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int finishrequire(lua_State* L)
|
||||
{
|
||||
if (lua_isstring(L, -1))
|
||||
lua_error(L);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int LUA_require(lua_State* L) {
|
||||
const char* name = luaL_checkstring(L, 1);
|
||||
|
||||
luaL_findtable(L, LUA_REGISTRYINDEX, "_MODULES", 1);
|
||||
|
||||
// return the module from the cache
|
||||
lua_getfield(L, -1, name);
|
||||
if (!lua_isnil(L, -1))
|
||||
{
|
||||
// L stack: _MODULES result
|
||||
return finishrequire(L);
|
||||
}
|
||||
|
||||
lua_pop(L, 1);
|
||||
|
||||
Engine* engine = LuaWrapper::toType<Engine*>(L, lua_upvalueindex(1));
|
||||
StaticString<MAX_PATH> path(name, ".lua");
|
||||
OutputMemoryStream blob(engine->getAllocator());
|
||||
if (!engine->getFileSystem().getContentSync(Path(path), blob)) {
|
||||
luaL_argerrorL(L, 1, "error loading module");
|
||||
}
|
||||
|
||||
// module needs to run in a new thread, isolated from the rest
|
||||
// note: we create ML on main thread so that it doesn't inherit environment of L
|
||||
lua_State* GL = lua_mainthread(L);
|
||||
lua_State* ML = lua_newthread(GL);
|
||||
lua_xmove(GL, L, 1);
|
||||
|
||||
// new thread needs to have the globals sandboxed
|
||||
luaL_sandboxthread(ML);
|
||||
|
||||
// now we can compile & run module on the new thread
|
||||
size_t bytecode_size;
|
||||
char* bytecode = luau_compile((const char*)blob.data(), blob.size(), nullptr, &bytecode_size);
|
||||
if (luau_load(ML, name, bytecode, bytecode_size, 0) == 0)
|
||||
{
|
||||
int status = lua_resume(ML, L, 0);
|
||||
|
||||
if (status == 0)
|
||||
{
|
||||
if (lua_gettop(ML) == 0)
|
||||
lua_pushstring(ML, "module must return a value");
|
||||
else if (!lua_istable(ML, -1) && !lua_isfunction(ML, -1))
|
||||
lua_pushstring(ML, "module must return a table or function");
|
||||
}
|
||||
else if (status == LUA_YIELD)
|
||||
{
|
||||
lua_pushstring(ML, "module can not yield");
|
||||
}
|
||||
else if (!lua_isstring(ML, -1))
|
||||
{
|
||||
lua_pushstring(ML, "unknown error while running module");
|
||||
}
|
||||
}
|
||||
free(bytecode);
|
||||
|
||||
// there's now a return value on top of ML; L stack: _MODULES ML
|
||||
lua_xmove(ML, L, 1);
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, -4, name);
|
||||
|
||||
// L stack: _MODULES ML result
|
||||
return finishrequire(L);
|
||||
}
|
||||
|
||||
static int LUA_instantiatePrefab(lua_State* L) {
|
||||
Engine* engine = getEngineUpvalue(L);
|
||||
LuaWrapper::checkTableArg(L, 1);
|
||||
|
@ -751,6 +767,10 @@ static int LUA_instantiatePrefab(lua_State* L) {
|
|||
|
||||
void registerEngineAPI(lua_State* L, Engine* engine)
|
||||
{
|
||||
lua_pushlightuserdata(L, engine);
|
||||
lua_pushcclosure(L, &LUA_require, "require", 1);
|
||||
lua_setglobal(L, "require");
|
||||
|
||||
LuaWrapper::createSystemVariable(L, "LumixAPI", "engine", engine);
|
||||
|
||||
#define REGISTER_FUNCTION(name) \
|
||||
|
@ -1008,8 +1028,6 @@ void registerEngineAPI(lua_State* L, Engine* engine)
|
|||
if (!LuaWrapper::execute(L, entity_src, __FILE__ "(" TO_STR(__LINE__) ")", 0)) {
|
||||
logError("Failed to init entity api");
|
||||
}
|
||||
|
||||
installLuaPackageLoader(L);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "lua_wrapper.h"
|
||||
#include "log.h"
|
||||
#include "string.h"
|
||||
#include <luacode.h>
|
||||
|
||||
namespace Lumix::LuaWrapper {
|
||||
|
||||
|
@ -59,7 +60,7 @@ int traceback(lua_State *L) {
|
|||
|
||||
bool pcall(lua_State* L, int nargs, int nres)
|
||||
{
|
||||
lua_pushcfunction(L, traceback);
|
||||
lua_pushcfunction(L, traceback, "traceback");
|
||||
lua_insert(L, -2 - nargs);
|
||||
if (lua_pcall(L, nargs, nres, -2 - nargs) != 0) {
|
||||
logError(lua_tostring(L, -1));
|
||||
|
@ -76,8 +77,13 @@ bool execute(lua_State* L
|
|||
, const char* name
|
||||
, int nresults)
|
||||
{
|
||||
lua_pushcfunction(L, traceback);
|
||||
if (luaL_loadbuffer(L, content.begin, content.size(), name) != 0) {
|
||||
lua_pushcfunction(L, traceback, "traceback");
|
||||
|
||||
size_t bytecodeSize = 0;
|
||||
char* bytecode = luau_compile((const char*)content.begin, content.size(), NULL, &bytecodeSize);
|
||||
int res = luau_load(L, name, bytecode, bytecodeSize, 0);
|
||||
free(bytecode);
|
||||
if (res != 0) {
|
||||
logError(name, ": ", lua_tostring(L, -1));
|
||||
lua_pop(L, 2);
|
||||
return false;
|
||||
|
@ -145,6 +151,25 @@ void pushEntity(lua_State* L, EntityPtr value, World* world) {
|
|||
ASSERT(!error);
|
||||
}
|
||||
|
||||
int luaL_loadbuffer(lua_State* L, const char* buff, size_t size, const char* name) {
|
||||
size_t bytecode_size;
|
||||
char* bytecode = luau_compile(buff, size, nullptr, &bytecode_size);
|
||||
if (!bytecode) return 1;
|
||||
int res = luau_load(L, name ? name : "N/A", bytecode, bytecode_size, 0);
|
||||
free(bytecode);
|
||||
return res;
|
||||
}
|
||||
|
||||
void luaL_unref(lua_State* L, int t, int ref) {
|
||||
lua_unref(L, ref);
|
||||
}
|
||||
|
||||
int luaL_ref(lua_State* L, int idx) {
|
||||
int r = lua_ref(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return r;
|
||||
}
|
||||
|
||||
int getField(lua_State* L, int idx, const char* k) {
|
||||
lua_getfield(L, idx, k);
|
||||
return lua_type(L, -1);
|
||||
|
@ -202,7 +227,7 @@ void createSystemFunction(lua_State* L, const char* system, const char* var_name
|
|||
lua_setglobal(L, system);
|
||||
lua_getglobal(L, system);
|
||||
}
|
||||
lua_pushcfunction(L, fn);
|
||||
lua_pushcfunction(L, fn, var_name);
|
||||
lua_setfield(L, -2, var_name);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
@ -216,7 +241,7 @@ void createSystemClosure(lua_State* L, const char* system, void* system_ptr, con
|
|||
lua_getglobal(L, system);
|
||||
}
|
||||
lua_pushlightuserdata(L, system_ptr);
|
||||
lua_pushcclosure(L, fn, 1);
|
||||
lua_pushcclosure(L, fn, var_name, 1);
|
||||
lua_setfield(L, -2, var_name);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
#include "engine/math.h"
|
||||
#include "engine/metaprogramming.h"
|
||||
#include "engine/path.h"
|
||||
#include <lua.hpp>
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
#include <lualib.h>
|
||||
|
||||
namespace Lumix {
|
||||
|
||||
|
@ -53,6 +53,9 @@ LUMIX_ENGINE_API int traceback (lua_State *L);
|
|||
LUMIX_ENGINE_API bool pcall(lua_State* L, int nargs, int nres);
|
||||
LUMIX_ENGINE_API bool execute(lua_State* L, StringView content, const char* name, int nresults);
|
||||
LUMIX_ENGINE_API int getField(lua_State* L, int idx, const char* k);
|
||||
LUMIX_ENGINE_API void luaL_unref(lua_State* L, int t, int ref);
|
||||
LUMIX_ENGINE_API int luaL_ref(lua_State* L, int idx);
|
||||
LUMIX_ENGINE_API int luaL_loadbuffer(lua_State* L, const char* buff, size_t size, const char* name);
|
||||
|
||||
template <typename T> inline bool isType(lua_State* L, int index)
|
||||
{
|
||||
|
@ -533,13 +536,13 @@ inline void push(lua_State* L, u8 value)
|
|||
{
|
||||
lua_pushinteger(L, value);
|
||||
}
|
||||
inline void push(lua_State* L, unsigned int value)
|
||||
inline void push(lua_State* L, u32 value)
|
||||
{
|
||||
lua_pushinteger(L, value);
|
||||
}
|
||||
inline void push(lua_State* L, u64 value)
|
||||
{
|
||||
lua_pushinteger(L, value);
|
||||
lua_pushnumber(L, double(value));
|
||||
}
|
||||
template <> inline void push(lua_State* L, void* value)
|
||||
{
|
||||
|
@ -822,7 +825,7 @@ template <auto t> int wrapMethodClosure(lua_State* L)
|
|||
int index = lua_upvalueindex(1);
|
||||
if (!isType<C>(L, index)) {
|
||||
ASSERT(false);
|
||||
return luaL_error(L, "Invalid Lua closure");
|
||||
luaL_error(L, "Invalid Lua closure");
|
||||
}
|
||||
auto* inst = checkArg<C*>(L, index);
|
||||
return details::Caller<indices>::callMethod(inst, t, L);
|
||||
|
|
|
@ -111,7 +111,7 @@ bool Sprite::load(Span<const u8> mem) {
|
|||
lua_State* L = luaL_newstate();
|
||||
|
||||
#define DEFINE_LUA_FUNC(func) \
|
||||
lua_pushcfunction(L, LuaSpriteAPI::func); \
|
||||
lua_pushcfunction(L, LuaSpriteAPI::func, #func); \
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, #func);
|
||||
|
||||
DEFINE_LUA_FUNC(type);
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
#include "engine/world.h"
|
||||
#include "lua_script/lua_script.h"
|
||||
#include "lua_script/lua_script_system.h"
|
||||
#include <lua.hpp>
|
||||
#include <lua.h>
|
||||
|
||||
|
||||
using namespace Lumix;
|
||||
|
@ -143,7 +143,6 @@ struct ConsolePlugin final : StudioApp::GUIPlugin
|
|||
m_toggle_ui.is_selected.bind<&ConsolePlugin::isOpen>(this);
|
||||
app.addWindowAction(&m_toggle_ui);
|
||||
buf[0] = '\0';
|
||||
runEditorLua();
|
||||
}
|
||||
|
||||
~ConsolePlugin() {
|
||||
|
@ -294,7 +293,6 @@ struct ConsolePlugin final : StudioApp::GUIPlugin
|
|||
void onGUI() override
|
||||
{
|
||||
if (!open) return;
|
||||
tickEditorLua();
|
||||
if (ImGui::Begin("Lua console##lua_console", &open))
|
||||
{
|
||||
if (ImGui::Button("Execute")) {
|
||||
|
@ -313,7 +311,7 @@ struct ConsolePlugin final : StudioApp::GUIPlugin
|
|||
else {
|
||||
L = app.getEngine().getState();
|
||||
|
||||
bool errors = luaL_loadbuffer(L, buf, stringLength(buf), nullptr) != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(L, buf, stringLength(buf), nullptr) != 0;
|
||||
errors = errors || lua_pcall(L, 0, 0, 0) != 0;
|
||||
|
||||
if (errors)
|
||||
|
@ -342,7 +340,7 @@ struct ConsolePlugin final : StudioApp::GUIPlugin
|
|||
}
|
||||
file.close();
|
||||
lua_State* L = app.getEngine().getState();
|
||||
bool errors = luaL_loadbuffer(L, &data[0], data.size(), tmp) != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(L, &data[0], data.size(), tmp) != 0;
|
||||
errors = errors || lua_pcall(L, 0, 0, 0) != 0;
|
||||
|
||||
if (errors)
|
||||
|
@ -401,48 +399,6 @@ struct ConsolePlugin final : StudioApp::GUIPlugin
|
|||
ImGui::End();
|
||||
}
|
||||
|
||||
|
||||
void runEditorLua() {
|
||||
OutputMemoryStream blob(app.getAllocator());
|
||||
const char* path = "scripts/editor_main.lua";
|
||||
Engine& engine = app.getEngine();
|
||||
if (!engine.getFileSystem().getContentSync(Path(path), blob)) return;
|
||||
|
||||
StringView sv;
|
||||
sv.begin = (const char*)blob.data();
|
||||
sv.end = sv.begin + blob.size();
|
||||
if (LuaWrapper::execute(engine.getState(), sv, path, 1)) {
|
||||
if (lua_isthread(engine.getState(), -1)) {
|
||||
m_editor_lua_state_ref = luaL_ref(engine.getState(), LUA_REGISTRYINDEX);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tickEditorLua() {
|
||||
if (m_editor_lua_state_ref == -1) return;
|
||||
|
||||
Engine& engine = app.getEngine();
|
||||
lua_State* L = engine.getState();
|
||||
LuaWrapper::DebugGuard guard(L);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, m_editor_lua_state_ref);
|
||||
lua_State* coroutine = lua_tothread(L, -1);
|
||||
i32 res = lua_resume(coroutine, 0);
|
||||
if (res == LUA_OK) {
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, m_editor_lua_state_ref);
|
||||
m_editor_lua_state_ref = -1;
|
||||
}
|
||||
else if (res != LUA_YIELD) {
|
||||
const char* error_msg2 = lua_tostring(coroutine, -1);
|
||||
logError("editor main: ", error_msg2);
|
||||
LuaWrapper::traceback(coroutine);
|
||||
const char* error_msg = lua_tostring(coroutine, -1);
|
||||
logError("editor main: ", error_msg);
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, m_editor_lua_state_ref);
|
||||
m_editor_lua_state_ref = -1;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
StudioApp& app;
|
||||
Action m_toggle_ui;
|
||||
Array<String> autocomplete;
|
||||
|
@ -452,7 +408,6 @@ struct ConsolePlugin final : StudioApp::GUIPlugin
|
|||
int autocomplete_selected = 1;
|
||||
const char* insert_value = nullptr;
|
||||
char buf[10 * 1024];
|
||||
i32 m_editor_lua_state_ref = -1;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -192,14 +192,15 @@ namespace Lumix
|
|||
lua_setfield(L, -2, "__index"); // [LumixAPI, obj]
|
||||
}
|
||||
lua_pushlightuserdata(L, f); // [LumixAPI, obj, f]
|
||||
lua_pushcclosure(L, luaMethodClosure, 1); // [LumixAPI, obj, closure]
|
||||
|
||||
if (f->name) {
|
||||
lua_pushcclosure(L, luaMethodClosure, f->name, 1); // [LumixAPI, obj, closure]
|
||||
lua_setfield(L, -2, f->name);
|
||||
} else {
|
||||
const char* fn_name = f->decl_code + strlen(f->decl_code);
|
||||
while (*fn_name != ':' && fn_name != f->decl_code) --fn_name;
|
||||
if (*fn_name == ':') ++fn_name;
|
||||
lua_pushcclosure(L, luaMethodClosure, fn_name, 1); // [LumixAPI, obj, closure]
|
||||
lua_setfield(L, -2, fn_name);
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
|
@ -333,11 +334,11 @@ namespace Lumix
|
|||
Engine& engine = module.m_system.m_engine;
|
||||
lua_State* L = engine.getState();
|
||||
m_state = lua_newthread(L);
|
||||
m_thread_ref = luaL_ref(L, LUA_REGISTRYINDEX); // []
|
||||
m_thread_ref = LuaWrapper::luaL_ref(L, LUA_REGISTRYINDEX); // []
|
||||
lua_newtable(m_state); // [env]
|
||||
// reference environment
|
||||
lua_pushvalue(m_state, -1); // [env, env]
|
||||
m_environment = luaL_ref(m_state, LUA_REGISTRYINDEX); // [env]
|
||||
m_environment = LuaWrapper::luaL_ref(m_state, LUA_REGISTRYINDEX); // [env]
|
||||
|
||||
// environment's metatable & __index
|
||||
lua_pushvalue(m_state, -1); // [env, env]
|
||||
|
@ -414,8 +415,8 @@ namespace Lumix
|
|||
|
||||
Engine& engine = m_cmp->m_module.m_system.m_engine;
|
||||
lua_State* L = engine.getState();
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, m_thread_ref);
|
||||
luaL_unref(m_state, LUA_REGISTRYINDEX, m_environment);
|
||||
LuaWrapper::luaL_unref(L, LUA_REGISTRYINDEX, m_thread_ref);
|
||||
LuaWrapper::luaL_unref(m_state, LUA_REGISTRYINDEX, m_environment);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -437,11 +438,11 @@ namespace Lumix
|
|||
Engine& engine = module.m_system.m_engine;
|
||||
lua_State* L = engine.getState();
|
||||
m_state = lua_newthread(L);
|
||||
m_thread_ref = luaL_ref(L, LUA_REGISTRYINDEX); // []
|
||||
m_thread_ref = LuaWrapper::luaL_ref(L, LUA_REGISTRYINDEX); // []
|
||||
lua_newtable(m_state); // [env]
|
||||
// reference environment
|
||||
lua_pushvalue(m_state, -1); // [env, env]
|
||||
m_environment = luaL_ref(m_state, LUA_REGISTRYINDEX); // [env]
|
||||
m_environment = LuaWrapper::luaL_ref(m_state, LUA_REGISTRYINDEX); // [env]
|
||||
|
||||
// environment's metatable & __index
|
||||
lua_pushvalue(m_state, -1); // [env, env]
|
||||
|
@ -483,15 +484,15 @@ namespace Lumix
|
|||
|
||||
Engine& engine = m_module.m_system.m_engine;
|
||||
lua_State* L = engine.getState();
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, m_thread_ref);
|
||||
luaL_unref(m_state, LUA_REGISTRYINDEX, m_environment);
|
||||
LuaWrapper::luaL_unref(L, LUA_REGISTRYINDEX, m_thread_ref);
|
||||
LuaWrapper::luaL_unref(m_state, LUA_REGISTRYINDEX, m_environment);
|
||||
}
|
||||
|
||||
void runSource() {
|
||||
lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_environment); // [env]
|
||||
ASSERT(lua_type(m_state, -1) == LUA_TTABLE);
|
||||
|
||||
bool errors = luaL_loadbuffer(m_state, m_source.c_str(), m_source.length(), "inline script") != 0; // [env, func]
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(m_state, m_source.c_str(), m_source.length(), "inline script") != 0; // [env, func]
|
||||
|
||||
if (errors) {
|
||||
logError("Inline script, entity ", m_entity.index ,": ", lua_tostring(m_state, -1));
|
||||
|
@ -808,7 +809,7 @@ namespace Lumix
|
|||
lua_State* state = script.m_state;
|
||||
if (!state) return false;
|
||||
|
||||
bool errors = luaL_loadbuffer(state, code.begin, code.size(), nullptr) != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(state, code.begin, code.size(), nullptr) != 0;
|
||||
if (errors) {
|
||||
logError(lua_tostring(state, -1));
|
||||
lua_pop(state, 1);
|
||||
|
@ -1067,7 +1068,7 @@ namespace Lumix
|
|||
LuaWrapper::push(L, entity_index);
|
||||
LuaWrapper::push(L, cmp_type);
|
||||
LuaWrapper::push(L, idx);
|
||||
lua_pushcclosure(L, getter, 5); // {}, mt, getter
|
||||
lua_pushcclosure(L, getter, "getter", 5); // {}, mt, getter
|
||||
lua_setfield(L, -2, "__index"); // {}, mt
|
||||
|
||||
lua_pushlightuserdata(L, (void*)prop);
|
||||
|
@ -1075,7 +1076,7 @@ namespace Lumix
|
|||
LuaWrapper::push(L, entity_index);
|
||||
LuaWrapper::push(L, cmp_type);
|
||||
LuaWrapper::push(L, idx);
|
||||
lua_pushcclosure(L, setter, 5); // {}, mt, getter
|
||||
lua_pushcclosure(L, setter, "setter", 5); // {}, mt, getter
|
||||
lua_setfield(L, -2, "__newindex"); // {}, mt
|
||||
|
||||
lua_setmetatable(L, -2); // {}
|
||||
|
@ -1087,7 +1088,7 @@ namespace Lumix
|
|||
lua_pushlightuserdata(L, (void*)cmp.module); // {}, mt, &prop, module
|
||||
LuaWrapper::push(L, cmp.entity.index); // {}, mt, &prop, module, entity.index
|
||||
LuaWrapper::push(L, cmp.type); // {}, mt, &prop, module, entity.index, cmp_type
|
||||
lua_pushcclosure(L, getter, 4); // {}, mt, getter
|
||||
lua_pushcclosure(L, getter, "getter", 4); // {}, mt, getter
|
||||
lua_setfield(L, -2, "__index"); // {}, mt
|
||||
lua_setmetatable(L, -2); // {}
|
||||
}
|
||||
|
@ -1277,7 +1278,7 @@ namespace Lumix
|
|||
for (auto* f : cmp->functions) {
|
||||
if (equalStrings(v.prop_name, f->name)) {
|
||||
lua_pushlightuserdata(L, (void*)f);
|
||||
lua_pushcclosure(L, luaCmpMethodClosure, 1);
|
||||
lua_pushcclosure(L, luaCmpMethodClosure, f->name, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -1338,7 +1339,7 @@ namespace Lumix
|
|||
lua_pushvalue(L, -1); // [ module, module ]
|
||||
lua_setfield(L, -2, "__index"); // [ module ]
|
||||
|
||||
lua_pushcfunction(L, lua_new_module); // [ module, fn_new_module ]
|
||||
lua_pushcfunction(L, lua_new_module, "new"); // [ module, fn_new_module ]
|
||||
lua_setfield(L, -2, "new"); // [ module ]
|
||||
|
||||
for (const reflection::FunctionBase* f : module->functions) {
|
||||
|
@ -1347,7 +1348,7 @@ namespace Lumix
|
|||
ASSERT(*c == ':');
|
||||
c += 2;
|
||||
lua_pushlightuserdata(L, (void*)f); // [module, f]
|
||||
lua_pushcclosure(L, luaModuleMethodClosure, 1); // [module, fn]
|
||||
lua_pushcclosure(L, luaModuleMethodClosure, c, 1); // [module, fn]
|
||||
lua_setfield(L, -2, c); // [module]
|
||||
}
|
||||
lua_pop(L, 1); // []
|
||||
|
@ -1365,17 +1366,17 @@ namespace Lumix
|
|||
lua_setfield(L, -2, cmp_name); // [ cmp, Lumix ]
|
||||
lua_pop(L, 1); // [ cmp ]
|
||||
|
||||
lua_pushcfunction(L, lua_new_cmp); // [ cmp, fn_new_cmp ]
|
||||
lua_pushcfunction(L, lua_new_cmp, "new"); // [ cmp, fn_new_cmp ]
|
||||
lua_setfield(L, -2, "new"); // [ cmp ]
|
||||
|
||||
LuaWrapper::setField(L, -1, "cmp_type", cmp_type.index);
|
||||
|
||||
LuaWrapper::push(L, cmp_type); // [ cmp, cmp_type ]
|
||||
lua_pushcclosure(L, lua_prop_getter, 1); // [ cmp, fn_prop_getter ]
|
||||
lua_pushcclosure(L, lua_prop_getter, "getter", 1); // [ cmp, fn_prop_getter ]
|
||||
lua_setfield(L, -2, "__index"); // [ cmp ]
|
||||
|
||||
LuaWrapper::push(L, cmp_type); // [ cmp, cmp_type ]
|
||||
lua_pushcclosure(L, lua_prop_setter, 1); // [ cmp, fn_prop_setter ]
|
||||
lua_pushcclosure(L, lua_prop_setter, "setter", 1); // [ cmp, fn_prop_setter ]
|
||||
lua_setfield(L, -2, "__newindex"); // [ cmp ]
|
||||
|
||||
lua_pop(L, 1);
|
||||
|
@ -1404,7 +1405,7 @@ namespace Lumix
|
|||
timer.time = time;
|
||||
timer.state = L;
|
||||
lua_pushvalue(L, 3);
|
||||
timer.func = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
timer.func = LuaWrapper::luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
lua_pop(L, 1);
|
||||
LuaWrapper::push(L, timer.func);
|
||||
return 1;
|
||||
|
@ -1544,7 +1545,7 @@ namespace Lumix
|
|||
if (prop.type == Property::STRING) tmp.append("\"", value, "\"");
|
||||
else tmp.append(value);
|
||||
|
||||
bool errors = luaL_loadbuffer(state, tmp, stringLength(tmp), nullptr) != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(state, tmp, stringLength(tmp), nullptr) != 0;
|
||||
if (errors)
|
||||
{
|
||||
logError(script.m_script->getPath(), ": ", lua_tostring(state, -1));
|
||||
|
@ -1618,7 +1619,7 @@ namespace Lumix
|
|||
{
|
||||
if (m_timers[i].state == inst.m_state)
|
||||
{
|
||||
luaL_unref(m_timers[i].state, LUA_REGISTRYINDEX, m_timers[i].func);
|
||||
LuaWrapper::luaL_unref(m_timers[i].state, LUA_REGISTRYINDEX, m_timers[i].func);
|
||||
m_timers.swapAndPop(i);
|
||||
--i;
|
||||
}
|
||||
|
@ -2113,7 +2114,7 @@ namespace Lumix
|
|||
for (u32 i = timers_to_remove_count - 1; i != 0xffFFffFF; --i)
|
||||
{
|
||||
auto& timer = m_timers[timers_to_remove[i]];
|
||||
luaL_unref(timer.state, LUA_REGISTRYINDEX, timer.func);
|
||||
LuaWrapper::luaL_unref(timer.state, LUA_REGISTRYINDEX, timer.func);
|
||||
m_timers.swapAndPop(timers_to_remove[i]);
|
||||
}
|
||||
}
|
||||
|
@ -2412,7 +2413,7 @@ namespace Lumix
|
|||
lua_rawgeti(m_state, LUA_REGISTRYINDEX, m_environment); // [env]
|
||||
ASSERT(lua_type(m_state, -1) == LUA_TTABLE);
|
||||
|
||||
bool errors = luaL_loadbuffer(m_state,
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(m_state,
|
||||
m_script->getSourceCode().begin,
|
||||
m_script->getSourceCode().size(),
|
||||
m_script->getPath().c_str()) != 0; // [env, func]
|
||||
|
|
|
@ -180,7 +180,7 @@ PhysicsMaterialManager::PhysicsMaterialManager(PhysicsSystem& system, IAllocator
|
|||
{
|
||||
state = luaL_newstate();
|
||||
#define DEFINE_LUA_FUNC(func) \
|
||||
lua_pushcfunction(state, LuaAPI::func); \
|
||||
lua_pushcfunction(state, LuaAPI::func, #func); \
|
||||
lua_setfield(state, LUA_GLOBALSINDEX, #func);
|
||||
|
||||
DEFINE_LUA_FUNC(static_friction);
|
||||
|
|
|
@ -3209,45 +3209,32 @@ struct ShaderPlugin final : AssetBrowser::IPlugin, AssetCompiler::IPlugin {
|
|||
return 0;
|
||||
};
|
||||
|
||||
lua_pushcclosure(L, reg_dep, 0);
|
||||
lua_pushcclosure(L, reg_dep, "include", 0);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "include");
|
||||
lua_pushcclosure(L, reg_dep, 0);
|
||||
lua_pushcclosure(L, reg_dep, "import", 0);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "import");
|
||||
|
||||
static const char* preface =
|
||||
"local new_g = setmetatable({include = include, import = import}, {__index = function() return function() end end })\n"
|
||||
"setfenv(1, new_g)\n";
|
||||
|
||||
auto reader = [](lua_State* L, void* data, size_t* size) -> const char* {
|
||||
Context* ctx = (Context*)data;
|
||||
++ctx->idx;
|
||||
switch(ctx->idx) {
|
||||
case 1:
|
||||
*size = stringLength(preface);
|
||||
return preface;
|
||||
case 2:
|
||||
*size = ctx->content_len;
|
||||
return (const char*)ctx->content;
|
||||
default:
|
||||
*size = 0;
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
if (lua_load(L, reader, &ctx, path.c_str()) != 0) {
|
||||
OutputMemoryStream tmp(m_app.getAllocator());
|
||||
tmp.write(preface, stringLength(preface));
|
||||
tmp.write(content.data(), content.size());
|
||||
|
||||
if (LuaWrapper::luaL_loadbuffer(L, (const char*)tmp.data(), tmp.size(), path.c_str()) != 0) {
|
||||
logError(path, ": ", lua_tostring(L, -1));
|
||||
lua_pop(L, 2);
|
||||
lua_close(L);
|
||||
return;
|
||||
}
|
||||
|
||||
if (lua_pcall(L, 0, 0, -2) != 0) {
|
||||
if (lua_pcall(L, 0, 0, 0) != 0) {
|
||||
logError(lua_tostring(L, -1));
|
||||
lua_pop(L, 2);
|
||||
lua_close(L);
|
||||
return;
|
||||
}
|
||||
lua_pop(L, 1);
|
||||
lua_close(L);
|
||||
}
|
||||
|
||||
|
|
|
@ -715,7 +715,7 @@ MaterialManager::MaterialManager(Renderer& renderer, IAllocator& allocator)
|
|||
m_state = luaL_newstate();
|
||||
|
||||
#define DEFINE_LUA_FUNC(func) \
|
||||
lua_pushcfunction(m_state, LuaAPI::func); \
|
||||
lua_pushcfunction(m_state, LuaAPI::func, #func); \
|
||||
lua_setfield(m_state, LUA_GLOBALSINDEX, #func);
|
||||
|
||||
DEFINE_LUA_FUNC(alpha_ref);
|
||||
|
@ -731,10 +731,10 @@ MaterialManager::MaterialManager(Renderer& renderer, IAllocator& allocator)
|
|||
DEFINE_LUA_FUNC(shader);
|
||||
DEFINE_LUA_FUNC(texture);
|
||||
|
||||
lua_pushcfunction(m_state, &Material::uniform);
|
||||
lua_pushcfunction(m_state, &Material::uniform, "uniform");
|
||||
lua_setfield(m_state, LUA_GLOBALSINDEX, "uniform");
|
||||
|
||||
lua_pushcfunction(m_state, &Material::int_uniform);
|
||||
lua_pushcfunction(m_state, &Material::int_uniform, "int_uniform");
|
||||
lua_setfield(m_state, LUA_GLOBALSINDEX, "int_uniform");
|
||||
|
||||
#undef DEFINE_LUA_FUNC
|
||||
|
|
|
@ -833,8 +833,8 @@ struct PipelineImpl final : Pipeline
|
|||
{
|
||||
if (m_lua_state)
|
||||
{
|
||||
luaL_unref(m_renderer.getEngine().getState(), LUA_REGISTRYINDEX, m_lua_thread_ref);
|
||||
luaL_unref(m_lua_state, LUA_REGISTRYINDEX, m_lua_env);
|
||||
LuaWrapper::luaL_unref(m_renderer.getEngine().getState(), LUA_REGISTRYINDEX, m_lua_thread_ref);
|
||||
LuaWrapper::luaL_unref(m_lua_state, LUA_REGISTRYINDEX, m_lua_env);
|
||||
m_lua_state = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -844,7 +844,7 @@ struct PipelineImpl final : Pipeline
|
|||
if (m_define == "") return;
|
||||
StaticString<256> tmp(m_define, " = true");
|
||||
|
||||
bool errors = luaL_loadbuffer(m_lua_state, tmp, stringLength(tmp), m_resource->getPath().c_str()) != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(m_lua_state, tmp, stringLength(tmp), m_resource->getPath().c_str()) != 0;
|
||||
if (errors)
|
||||
{
|
||||
logError(m_resource->getPath(), ": ", lua_tostring(m_lua_state, -1));
|
||||
|
@ -879,7 +879,7 @@ struct PipelineImpl final : Pipeline
|
|||
|
||||
StaticString<1024> tmp("function ", handler.name, "() executeCustomCommand(\"", handler.name, "\") end");
|
||||
|
||||
bool errors = luaL_loadbuffer(m_lua_state, tmp, stringLength(tmp), "exposeCustomCommandToLua") != 0;
|
||||
bool errors = LuaWrapper::luaL_loadbuffer(m_lua_state, tmp, stringLength(tmp), "exposeCustomCommandToLua") != 0;
|
||||
lua_rawgeti(m_lua_state, LUA_REGISTRYINDEX, m_lua_env);
|
||||
lua_setfenv(m_lua_state, -2);
|
||||
errors = errors || lua_pcall(m_lua_state, 0, 0, 0) != 0;
|
||||
|
@ -898,11 +898,11 @@ struct PipelineImpl final : Pipeline
|
|||
cleanup();
|
||||
|
||||
m_lua_state = lua_newthread(m_renderer.getEngine().getState());
|
||||
m_lua_thread_ref = luaL_ref(m_renderer.getEngine().getState(), LUA_REGISTRYINDEX);
|
||||
m_lua_thread_ref = LuaWrapper::luaL_ref(m_renderer.getEngine().getState(), LUA_REGISTRYINDEX);
|
||||
|
||||
lua_newtable(m_lua_state);
|
||||
lua_pushvalue(m_lua_state, -1);
|
||||
m_lua_env = luaL_ref(m_lua_state, LUA_REGISTRYINDEX);
|
||||
m_lua_env = LuaWrapper::luaL_ref(m_lua_state, LUA_REGISTRYINDEX);
|
||||
lua_pushvalue(m_lua_state, -1);
|
||||
lua_setmetatable(m_lua_state, -2);
|
||||
lua_pushvalue(m_lua_state, LUA_GLOBALSINDEX);
|
||||
|
@ -923,11 +923,11 @@ struct PipelineImpl final : Pipeline
|
|||
}
|
||||
|
||||
setDefine();
|
||||
|
||||
|
||||
const char* content = m_resource->content.c_str();
|
||||
const int content_size = m_resource->content.length();
|
||||
bool errors =
|
||||
luaL_loadbuffer(m_lua_state, content, content_size, m_resource->getPath().c_str()) != 0;
|
||||
LuaWrapper::luaL_loadbuffer(m_lua_state, content, content_size, m_resource->getPath().c_str()) != 0;
|
||||
if (errors)
|
||||
{
|
||||
logError(m_resource->getPath(), ": ", lua_tostring(m_lua_state, -1));
|
||||
|
@ -944,7 +944,7 @@ struct PipelineImpl final : Pipeline
|
|||
lua_pop(m_lua_state, 1);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
m_viewport.w = m_viewport.h = 800;
|
||||
if (m_module) callInitModule();
|
||||
}
|
||||
|
@ -3829,7 +3829,7 @@ struct PipelineImpl final : Pipeline
|
|||
|
||||
auto registerCFunction = [L, this](const char* name, lua_CFunction function) {
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(L, function, 1);
|
||||
lua_pushcclosure(L, function, name, 1);
|
||||
lua_setfield(L, -3, name);
|
||||
};
|
||||
|
||||
|
@ -3914,7 +3914,7 @@ struct PipelineImpl final : Pipeline
|
|||
lua_getfield(L, -1, "Draw2D"); \
|
||||
} \
|
||||
lua_pushlightuserdata(L, &m_draw2d); \
|
||||
lua_pushcclosure(L, f, 1); \
|
||||
lua_pushcclosure(L, f, #fn_name, 1); \
|
||||
lua_setfield(L, -2, #fn_name); \
|
||||
lua_pop(L, 1); \
|
||||
} while(false) \
|
||||
|
|
|
@ -247,8 +247,7 @@ static void source(lua_State* L, gpu::ShaderType shader_type)
|
|||
stage.type = shader_type;
|
||||
|
||||
lua_Debug ar;
|
||||
lua_getstack(L, 1, &ar);
|
||||
lua_getinfo(L, "nSl", &ar);
|
||||
lua_getinfo(L, 1, "nSl", &ar);
|
||||
const int line = ar.currentline;
|
||||
ASSERT(line >= 0);
|
||||
|
||||
|
@ -270,8 +269,7 @@ static int common(lua_State* L)
|
|||
Shader* shader = getShader(L);
|
||||
|
||||
lua_Debug ar;
|
||||
lua_getstack(L, 1, &ar);
|
||||
lua_getinfo(L, "nSl", &ar);
|
||||
lua_getinfo(L, 1, "nSl", &ar);
|
||||
const int line = ar.currentline;
|
||||
ASSERT(line >= 0);
|
||||
|
||||
|
@ -357,38 +355,38 @@ int include(lua_State* L)
|
|||
bool Shader::load(Span<const u8> mem) {
|
||||
lua_State* root_state = m_renderer.getEngine().getState();
|
||||
lua_State* L = lua_newthread(root_state);
|
||||
const int state_ref = luaL_ref(root_state, LUA_REGISTRYINDEX);
|
||||
|
||||
const int state_ref = LuaWrapper::luaL_ref(root_state, LUA_REGISTRYINDEX);
|
||||
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "this");
|
||||
lua_pushcfunction(L, LuaAPI::common);
|
||||
lua_pushcfunction(L, LuaAPI::common, "common");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "common");
|
||||
lua_pushcfunction(L, LuaAPI::vertex_shader);
|
||||
lua_pushcfunction(L, LuaAPI::vertex_shader, "vertex_shader");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "vertex_shader");
|
||||
lua_pushcfunction(L, LuaAPI::fragment_shader);
|
||||
lua_pushcfunction(L, LuaAPI::fragment_shader, "fragment_shader");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "fragment_shader");
|
||||
lua_pushcfunction(L, LuaAPI::compute_shader);
|
||||
lua_pushcfunction(L, LuaAPI::compute_shader, "compute_shader");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "compute_shader");
|
||||
lua_pushcfunction(L, LuaAPI::geometry_shader);
|
||||
lua_pushcfunction(L, LuaAPI::geometry_shader, "geometry_shader");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "geometry_shader");
|
||||
lua_pushcfunction(L, LuaAPI::include);
|
||||
lua_pushcfunction(L, LuaAPI::include, "include");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "include");
|
||||
lua_pushcfunction(L, LuaAPI::import);
|
||||
lua_pushcfunction(L, LuaAPI::import, "import");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "import");
|
||||
lua_pushcfunction(L, LuaAPI::texture_slot);
|
||||
lua_pushcfunction(L, LuaAPI::texture_slot, "texture_slot");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "texture_slot");
|
||||
lua_pushcfunction(L, LuaAPI::define);
|
||||
lua_pushcfunction(L, LuaAPI::define, "define");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "define");
|
||||
lua_pushcfunction(L, LuaAPI::uniform);
|
||||
lua_pushcfunction(L, LuaAPI::uniform, "uniform");
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "uniform");
|
||||
|
||||
StringView content((const char*)mem.begin(), (u32)mem.length());
|
||||
if (!LuaWrapper::execute(L, content, getPath().c_str(), 0)) {
|
||||
luaL_unref(root_state, LUA_REGISTRYINDEX, state_ref);
|
||||
LuaWrapper::luaL_unref(root_state, LUA_REGISTRYINDEX, state_ref);
|
||||
return false;
|
||||
}
|
||||
|
||||
luaL_unref(root_state, LUA_REGISTRYINDEX, state_ref);
|
||||
LuaWrapper::luaL_unref(root_state, LUA_REGISTRYINDEX, state_ref);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue