Add / Remove Player (#2)

* addplayer and removeplayer

* add sqlite3 library and remove comment in library headers

* setup database system
This commit is contained in:
Notify-ctrl 2022-03-24 21:23:42 +08:00 committed by Notify-ctrl
parent d2315c7533
commit 432a306de0
65 changed files with 5087 additions and 3384 deletions

1
.gitignore vendored
View File

@ -7,3 +7,4 @@ build/
FreeKill
FreeKill.exe
freekill-wrap.cxx
server/users.db

View File

@ -10,6 +10,7 @@ find_package(Qt5 REQUIRED COMPONENTS
)
find_package(Lua)
find_package(SQLite3)
set(CMAKE_AUTOMOC ON)
set(CMAKE_CXX_STANDARD 11)
@ -18,6 +19,7 @@ set(REQUIRED_QT_VERSION "5.15.2")
include_directories(${PROJECT_SOURCE_DIR}/)
include_directories(include/lua)
include_directories(include/sqlite3)
include_directories(src)
include_directories(src/client)
include_directories(src/core)

7
doc/dev/database.md Normal file
View File

@ -0,0 +1,7 @@
# FreeKill 的数据库TODO
> [dev](./index.md) > 数据库
___
FreeKill 使用 sqlite3 数据库。

View File

@ -7,3 +7,5 @@ ___
FreeKill采用Qt框架提供底层支持在上层使用lua语言开发。在UI方面使用的是Qt Quick。
- [通信](./protocol.md)
- [数据库](./database.md)
- [UI](./ui.md)

View File

@ -33,4 +33,69 @@ $ ./FreeKill -s <port>
服务器以TCP方式监听。在默认情况下比如单机启动服务器的端口号是9527。
每当任何一个客户端连接上了之后,客户端进入大厅。
每当任何一个客户端连接上了之后,游戏会先进行以下流程:
1. 检查IP是否被封禁。 // TODO: 数据库
2. 检查客户端的延迟是否小于30秒。
3. 在网络检测环节,若客户端网速达标的话,客户端应该会发回一个字符串。这个字符串保存着用户的用户名和密码,服务端检查这个字符串是否合法。
4. 上述检查都通过后重连TODO
5. 不要重连的话,服务端便为新连接新建一个`ServerPlayer`对象,并将其添加到大厅中。
___
## 大厅和房间
大厅Lobby是一个比较特殊的房间。除了大厅之外所有的房间都被作为游戏房间对待。
对于普通房间而言,有这几个特点:
1. 只要房间被添加玩家,那么那名玩家就自动从大厅移除。
2. 当玩家离开房间时,玩家便会自动进入大厅。
3. 当所有玩家都离开房间后,房间被销毁。
大厅的特点:
1. 只要有玩家进入,就刷新一次房间列表。
> 因为上述特点都是通过信号槽实现的,通过阅读代码不易发现,故记录之。
___
## 对掉线的处理
因为每个连接都对应着一个`new ClientSocket`和`new ServerPlayer`,所以对于掉线的处理要慎重,处理不当会导致内存泄漏以及各种奇怪的错误。
一般来说掉线有以下几种情况:
1. 刚刚登入,服务端还在检测时掉线。
2. 在大厅里面掉线。
3. 在未开始游戏的房间里面掉线。
4. 在已开始游戏的房间里掉线。
首先对所有的这些情况都应该把ClientSocket释放掉。这部分代码写在[server_socket.cpp](../../src/network/server_socket.cpp)里面。
对于2、3两种情况都算是在游戏开始之前的房间中掉线。这种情况下直接从房间中删除这个玩家并告诉其他玩家一声然后从服务器玩家列表中也删除那名玩家。但对于情况3因为从普通房间删除玩家的话那名玩家会自动进入大厅所以需要大厅再删除一次玩家。
对于情况4因为游戏已经开始所以不能直接删除玩家需要把玩家的状态设为“离线”并继续游戏。在游戏结束后若玩家仍未重连则按情况2、3处理。
___
## 断线重连TODO
根据用户名找到掉线的那位玩家,将玩家的状态设置为“在线”,并将房间的状态都发送给他即可。
但是为了[UI不出错](./ui.md#mainStack),依然需要对重连的玩家走一遍进大厅的流程。
___
## 旁观TODO
因为房间不允许加入比玩家上限的玩家,可以考虑在房间里新建一个列表存储旁观中的玩家。但是这样或许会让某些处理(如掉线)变得复杂化。
也可以考虑旁观者在服务端中处于大厅中,自己的端中在旁观房间。但是这样的话无法在房间中发送聊天。
所以还是让旁观者在房间中吧。可以给ServerPlayer设置个属性保存正在旁观的房间的id。
旁观者的处理方式或许可以像观看录像那样过滤所有的request事件。这样就确确实实只能看着了。
而不过滤request的旁观就可以理解为操控其他玩家了。hhh

29
doc/dev/ui.md Normal file
View File

@ -0,0 +1,29 @@
# FreeKill 的UI
> [dev](./index.md) > UI
___
## 概述
FreeKill的UI系统使用Qt Quick开发。UI依赖[QmlBackend](../../src/ui/qmlbackend.h)调用需要的C++函数。关于这方面也可参考[main.cpp](../../src/main.cpp)。
> Note: 我感觉QmlBackend这种实现方式很尴尬。
整体UI采用StackView进行页面切换之类的。
___
## mainStack
mainStack定义于[main.qml](../../qml/main.qml)中。它以堆栈的形式保存着所有的页面,页面在栈中的顺序需要像这样排布:
- 栈底登录界面Init.qml
- 大厅Lobby.qml
- 别的什么页面
___
## config
Config.qml存储一些客户端需要用到的设置或者即将发送的数据TODO

View File

@ -1,8 +1,9 @@
/*
** $Id: lapi.h $
** Auxiliary functions from Lua API
** See Copyright Notice in lua.h
*/
# 1 "./lua/lapi.h"
#ifndef lapi_h
#define lapi_h
@ -12,37 +13,27 @@
#include "lstate.h"
/* Increments 'L->top', checking for stack overflows */
#define api_incr_top(L) {L->top++; api_check(L, L->top <= L->ci->top, \
"stack overflow");}
/*
** If a call returns too many multiple returns, the callee may not have
** stack space to accommodate all results. In this case, this macro
** increases its stack space ('L->ci->top').
*/
#define adjustresults(L,nres) \
{ if ((nres) <= LUA_MULTRET && L->ci->top < L->top) L->ci->top = L->top; }
/* Ensure the stack has at least 'n' elements */
#define api_checknelems(L,n) api_check(L, (n) < (L->top - L->ci->func), \
"not enough elements in the stack")
/*
** To reduce the overhead of returning from C functions, the presence of
** to-be-closed variables in these functions is coded in the CallInfo's
** field 'nresults', in a way that functions with no to-be-closed variables
** with zero, one, or "all" wanted results have no overhead. Functions
** with other number of wanted results, as well as functions with
** variables to be closed, have an extra check.
*/
# 43 "./lua/lapi.h"
#define hastocloseCfunc(n) ((n) < LUA_MULTRET)
/* Map [-1, inf) (range of 'nresults') into (-inf, -2] */
#define codeNresults(n) (-(n) - 3)
#define decodeNresults(n) (-(n) - 3)

View File

@ -1,8 +1,9 @@
/*
** $Id: lauxlib.h $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
# 1 "./lua/lauxlib.h"
#ifndef lauxlib_h
@ -16,22 +17,22 @@
#include "lua.h"
/* global table */
#define LUA_GNAME "_G"
typedef struct luaL_Buffer luaL_Buffer;
/* extra error code for 'luaL_loadfilex' */
#define LUA_ERRFILE (LUA_ERRERR+1)
/* key, in the registry, for table of loaded modules */
#define LUA_LOADED_TABLE "_LOADED"
/* key, in the registry, for table of preloaded loaders */
#define LUA_PRELOAD_TABLE "_PRELOAD"
@ -82,7 +83,7 @@ LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
LUALIB_API int (luaL_execresult) (lua_State *L, int stat);
/* predefined references */
#define LUA_NOREF (-2)
#define LUA_REFNIL (-1)
@ -116,14 +117,7 @@ LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1,
LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
lua_CFunction openf, int glb);
/*
** ===============================================================
** some useful macros
** ===============================================================
*/
# 127 "./lua/lauxlib.h"
#define luaL_newlibtable(L,l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
@ -154,21 +148,21 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_loadbuffer(L,s,sz,n) luaL_loadbufferx(L,s,sz,n,NULL)
/*
** Perform arithmetic operations on lua_Integer values with wrap-around
** semantics, as the Lua core does.
*/
#define luaL_intop(op,v1,v2) \
((lua_Integer)((lua_Unsigned)(v1) op (lua_Unsigned)(v2)))
/* push the value used to represent failure/error */
#define luaL_pushfail(L) lua_pushnil(L)
/*
** Internal assertions for in-house debugging
*/
#if !defined(lua_assert)
#if defined LUAI_ASSERT
@ -179,23 +173,15 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#endif
#endif
/*
** {======================================================
** Generic Buffer manipulation
** =======================================================
*/
# 191 "./lua/lauxlib.h"
struct luaL_Buffer {
char *b; /* buffer address */
size_t size; /* buffer size */
size_t n; /* number of characters in buffer */
char *b;
size_t size;
size_t n;
lua_State *L;
union {
LUAI_MAXALIGN; /* ensure maximum alignment for buffer */
char b[LUAL_BUFFERSIZE]; /* initial buffer */
LUAI_MAXALIGN;
char b[LUAL_BUFFERSIZE];
} init;
};
@ -222,63 +208,30 @@ LUALIB_API void (luaL_pushresultsize) (luaL_Buffer *B, size_t sz);
LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz);
#define luaL_prepbuffer(B) luaL_prepbuffsize(B, LUAL_BUFFERSIZE)
/* }====================================================== */
/*
** {======================================================
** File handles for IO library
** =======================================================
*/
/*
** A file handle is a userdata with metatable 'LUA_FILEHANDLE' and
** initial structure 'luaL_Stream' (it may contain other fields
** after that initial structure).
*/
# 242 "./lua/lauxlib.h"
#define LUA_FILEHANDLE "FILE*"
typedef struct luaL_Stream {
FILE *f; /* stream (NULL for incompletely created streams) */
lua_CFunction closef; /* to close stream (NULL for closed streams) */
FILE *f;
lua_CFunction closef;
} luaL_Stream;
/* }====================================================== */
/*
** {==================================================================
** "Abstraction Layer" for basic report of messages and errors
** ===================================================================
*/
/* print a string */
# 259 "./lua/lauxlib.h"
#if !defined(lua_writestring)
#define lua_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
#endif
/* print a newline and flush the output */
#if !defined(lua_writeline)
#define lua_writeline() (lua_writestring("\n", 1), fflush(stdout))
#endif
/* print an error message */
#if !defined(lua_writestringerror)
#define lua_writestringerror(s,p) \
(fprintf(stderr, (s), (p)), fflush(stderr))
#endif
/* }================================================================== */
/*
** {============================================================
** Compatibility with deprecated conversions
** =============================================================
*/
# 282 "./lua/lauxlib.h"
#if defined(LUA_COMPAT_APIINTCASTS)
#define luaL_checkunsigned(L,a) ((lua_Unsigned)luaL_checkinteger(L,a))
@ -292,10 +245,8 @@ typedef struct luaL_Stream {
#define luaL_optlong(L,n,d) ((long)luaL_optinteger(L, (n), (d)))
#endif
/* }============================================================ */
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lcode.h $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
# 1 "./lua/lcode.h"
#ifndef lcode_h
#define lcode_h
@ -13,35 +14,35 @@
#include "lparser.h"
/*
** Marks the end of a patch list. It is an invalid value both as an absolute
** address, and as a list link (would link an element to itself).
*/
#define NO_JUMP (-1)
/*
** grep "ORDER OPR" if you change these enums (ORDER OP)
*/
typedef enum BinOpr {
/* arithmetic operators */
OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
OPR_DIV, OPR_IDIV,
/* bitwise operators */
OPR_BAND, OPR_BOR, OPR_BXOR,
OPR_SHL, OPR_SHR,
/* string operator */
OPR_CONCAT,
/* comparison operators */
OPR_EQ, OPR_LT, OPR_LE,
OPR_NE, OPR_GT, OPR_GE,
/* logical operators */
OPR_AND, OPR_OR,
OPR_NOBINOPR
} BinOpr;
/* true if operation is foldable (that is, it is arithmetic or bitwise) */
#define foldbinop(op) ((op) <= OPR_SHR)
@ -51,7 +52,7 @@ typedef enum BinOpr {
typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
/* get (pointer to) instruction of given 'expdesc' */
#define getinstruction(fs,e) ((fs)->f->code[(e)->u.info])

View File

@ -1,35 +1,29 @@
/*
** $Id: lctype.h $
** 'ctype' functions for Lua
** See Copyright Notice in lua.h
*/
# 1 "./lua/lctype.h"
#ifndef lctype_h
#define lctype_h
#include "lua.h"
/*
** WARNING: the functions defined here do not necessarily correspond
** to the similar functions in the standard C ctype.h. They are
** optimized for the specific needs of Lua.
*/
# 19 "./lua/lctype.h"
#if !defined(LUA_USE_CTYPE)
#if 'A' == 65 && '0' == 48
/* ASCII case: can use its own tables; faster and fixed */
#define LUA_USE_CTYPE 0
#else
/* must use standard C ctype */
#define LUA_USE_CTYPE 1
#endif
#endif
#if !LUA_USE_CTYPE /* { */
#if !LUA_USE_CTYPE
#include <limits.h>
@ -46,42 +40,35 @@
#define MASK(B) (1 << (B))
/*
** add 1 to char to allow index -1 (EOZ)
*/
#define testprop(c,p) (luai_ctype_[(c)+1] & (p))
/*
** 'lalpha' (Lua alphabetic) and 'lalnum' (Lua alphanumeric) both include '_'
*/
#define lislalpha(c) testprop(c, MASK(ALPHABIT))
#define lislalnum(c) testprop(c, (MASK(ALPHABIT) | MASK(DIGITBIT)))
#define lisdigit(c) testprop(c, MASK(DIGITBIT))
#define lisspace(c) testprop(c, MASK(SPACEBIT))
#define lisprint(c) testprop(c, MASK(PRINTBIT))
#define lisxdigit(c) testprop(c, MASK(XDIGITBIT))
/*
** In ASCII, this 'ltolower' is correct for alphabetic characters and
** for '.'. That is enough for Lua needs. ('check_exp' ensures that
** the character either is an upper-case letter or is unchanged by
** the transformation, which holds for lower-case letters and '.'.)
*/
# 71 "./lua/lctype.h"
#define ltolower(c) \
check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \
(c) | ('A' ^ 'a'))
/* one entry for each character and for -1 (EOZ) */
LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];)
#else /* }{ */
#else
/*
** use standard C ctypes
*/
#include <ctype.h>
@ -95,7 +82,6 @@ LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];)
#define ltolower(c) (tolower(c))
#endif /* } */
#endif
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: ldebug.h $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
# 1 "./lua/ldebug.h"
#ifndef ldebug_h
#define ldebug_h
@ -14,23 +15,23 @@
#define pcRel(pc,p) (cast_int((pc) - (p)->code) - 1)
/* Active Lua function (given call info) */
#define ci_func(ci) (clLvalue(s2v((ci)->func)))
#define resethookcount(L) (L->hookcount = L->basehookcount)
/*
** mark for entries in 'lineinfo' array that has absolute information in
** 'abslineinfo' array
*/
#define ABSLINEINFO (-0x80)
/*
** MAXimum number of successive Instructions WiTHout ABSolute line
** information. (A power of two allows fast divisions.)
*/
#if !defined(MAXIWTHABS)
#define MAXIWTHABS 128
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: ldo.h $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
# 1 "./lua/ldo.h"
#ifndef ldo_h
#define ldo_h
@ -11,23 +12,13 @@
#include "lobject.h"
#include "lstate.h"
#include "lzio.h"
/*
** Macro to check stack size and grow stack if needed. Parameters
** 'pre'/'pos' allow the macro to preserve a pointer into the
** stack across reallocations, doing the work only when needed.
** It also allows the running of one GC step when the stack is
** reallocated.
** 'condmovestack' is used in heavy tests to force a stack reallocation
** at every check.
*/
# 25 "./lua/ldo.h"
#define luaD_checkstackaux(L,n,pre,pos) \
if (l_unlikely(L->stack_last - L->top <= (n))) \
{ pre; luaD_growstack(L, n, 1); pos; } \
else { condmovestack(L,pre,pos); }
/* In general, 'pre'/'pos' are empty (nothing to save) */
#define luaD_checkstack(L,n) luaD_checkstackaux(L,n,(void)0,(void)0)
@ -36,20 +27,20 @@
#define restorestack(L,n) ((StkId)((char *)L->stack + (n)))
/* macro to check stack size, preserving 'p' */
#define checkstackGCp(L,n,p) \
luaD_checkstackaux(L, n, \
ptrdiff_t t__ = savestack(L, p); /* save 'p' */ \
luaC_checkGC(L), /* stack grow uses memory */ \
p = restorestack(L, t__)) /* 'pos' part: restore 'p' */
ptrdiff_t t__ = savestack(L, p); \
luaC_checkGC(L), \
p = restorestack(L, t__))
/* macro to check stack size and GC */
#define checkstackGC(L,fsize) \
luaD_checkstackaux(L, (fsize), luaC_checkGC(L), (void)0)
/* type of protected functions, to be ran by 'runprotected' */
typedef void (*Pfunc) (lua_State *L, void *ud);
LUAI_FUNC void luaD_seterrorobj (lua_State *L, int errcode, StkId oldtop);
@ -76,4 +67,3 @@ LUAI_FUNC l_noret luaD_throw (lua_State *L, int errcode);
LUAI_FUNC int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud);
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lfunc.h $
** Auxiliary functions to manipulate prototypes and closures
** See Copyright Notice in lua.h
*/
# 1 "./lua/lfunc.h"
#ifndef lfunc_h
#define lfunc_h
@ -18,14 +19,14 @@
cast_int(sizeof(TValue *)) * (n))
/* test whether thread is in 'twups' list */
#define isintwups(L) (L->twups != L)
/*
** maximum number of upvalues in a closure (both C and Lua). (Value
** must fit in a VM register.)
*/
#define MAXUPVAL 255
@ -35,15 +36,15 @@
#define uplevel(up) check_exp(upisopen(up), cast(StkId, (up)->v))
/*
** maximum number of misses before giving up the cache of closures
** in prototypes
*/
#define MAXMISS 10
/* special status to close upvalues preserving the top of the stack */
#define CLOSEKTOP (-1)

View File

@ -1,8 +1,9 @@
/*
** $Id: lgc.h $
** Garbage Collector
** See Copyright Notice in lua.h
*/
# 1 "./lua/lgc.h"
#ifndef lgc_h
#define lgc_h
@ -10,24 +11,7 @@
#include "lobject.h"
#include "lstate.h"
/*
** Collectable objects may have one of three colors: white, which means
** the object is not marked; gray, which means the object is marked, but
** its references may be not marked; and black, which means that the
** object and all its references are marked. The main invariant of the
** garbage collector, while marking objects, is that a black object can
** never point to a white one. Moreover, any gray object must be in a
** "gray list" (gray, grayagain, weak, allweak, ephemeron) so that it
** can be visited again before finishing the collection cycle. (Open
** upvalues are an exception to this rule.) These lists have no meaning
** when the invariant is not being enforced (e.g., sweep phase).
*/
/*
** Possible states of the Garbage Collector
*/
# 31 "./lua/lgc.h"
#define GCSpropagate 0
#define GCSenteratomic 1
#define GCSatomic 2
@ -41,22 +25,13 @@
#define issweepphase(g) \
(GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
/*
** macro to tell when main invariant (white objects cannot point to black
** ones) must be kept. During a collection, the sweep
** phase may break the invariant, as objects turned white may point to
** still-black objects. The invariant is restored when sweep ends and
** all objects are white again.
*/
# 54 "./lua/lgc.h"
#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
/*
** some useful bit tricks
*/
#define resetbits(x,m) ((x) &= cast_byte(~(m)))
#define setbits(x,m) ((x) |= (m))
#define testbits(x,m) ((x) & (m))
@ -67,15 +42,15 @@
#define testbit(x,b) testbits(x, bitmask(b))
/*
** Layout for bit use in 'marked' field. First three bits are
** used for object "age" in generational mode. Last bit is used
** by tests.
*/
#define WHITE0BIT 3 /* object is white (type 0) */
#define WHITE1BIT 4 /* object is white (type 1) */
#define BLACKBIT 5 /* object is black */
#define FINALIZEDBIT 6 /* object has been marked for finalization */
#define WHITE0BIT 3
#define WHITE1BIT 4
#define BLACKBIT 5
#define FINALIZEDBIT 6
#define TESTBIT 7
@ -86,7 +61,7 @@
#define iswhite(x) testbits((x)->marked, WHITEBITS)
#define isblack(x) testbit((x)->marked, BLACKBIT)
#define isgray(x) /* neither white nor black */ \
#define isgray(x) \
(!testbits((x)->marked, WHITEBITS | bitmask(BLACKBIT)))
#define tofinalize(x) testbit((x)->marked, FINALIZEDBIT)
@ -102,16 +77,16 @@
#define luaC_white(g) cast_byte((g)->currentwhite & WHITEBITS)
/* object age in generational mode */
#define G_NEW 0 /* created in current cycle */
#define G_SURVIVAL 1 /* created in previous cycle */
#define G_OLD0 2 /* marked old by frw. barrier in this cycle */
#define G_OLD1 3 /* first full cycle as old */
#define G_OLD 4 /* really old object (not to be visited) */
#define G_TOUCHED1 5 /* old object touched this cycle */
#define G_TOUCHED2 6 /* old object touched in previous cycle */
#define AGEBITS 7 /* all age bits (111) */
#define G_NEW 0
#define G_SURVIVAL 1
#define G_OLD0 2
#define G_OLD1 3
#define G_OLD 4
#define G_TOUCHED1 5
#define G_TOUCHED2 6
#define AGEBITS 7
#define getage(o) ((o)->marked & AGEBITS)
#define setage(o,a) ((o)->marked = cast_byte(((o)->marked & (~AGEBITS)) | a))
@ -121,54 +96,47 @@
check_exp(getage(o) == (f), (o)->marked ^= ((f)^(t)))
/* Default Values for GC parameters */
#define LUAI_GENMAJORMUL 100
#define LUAI_GENMINORMUL 20
/* wait memory to double before starting new cycle */
#define LUAI_GCPAUSE 200
/*
** some gc parameters are stored divided by 4 to allow a maximum value
** up to 1023 in a 'lu_byte'.
*/
#define getgcparam(p) ((p) * 4)
#define setgcparam(p,v) ((p) = (v) / 4)
#define LUAI_GCMUL 100
/* how much to allocate before next GC step (log2) */
#define LUAI_GCSTEPSIZE 13 /* 8 KB */
#define LUAI_GCSTEPSIZE 13
/*
** Check whether the declared GC mode is generational. While in
** generational mode, the collector can go temporarily to incremental
** mode to improve performance. This is signaled by 'g->lastatomic != 0'.
*/
#define isdecGCmodegen(g) (g->gckind == KGC_GEN || g->lastatomic != 0)
/*
** Control when GC is running:
*/
#define GCSTPUSR 1 /* bit true when GC stopped by user */
#define GCSTPGC 2 /* bit true when GC stopped by itself */
#define GCSTPCLS 4 /* bit true when closing Lua state */
#define GCSTPUSR 1
#define GCSTPGC 2
#define GCSTPCLS 4
#define gcrunning(g) ((g)->gcstp == 0)
/*
** Does one step of collection when debt becomes positive. 'pre'/'pos'
** allows some adjustments to be done only when needed. macro
** 'condchangemem' is used only for heavy tests (forcing a full
** GC cycle on every opportunity)
*/
# 167 "./lua/lgc.h"
#define luaC_condGC(L,pre,pos) \
{ if (G(L)->GCdebt > 0) { pre; luaC_step(L); pos;}; \
condchangemem(L,pre,pos); }
/* more often than not, 'pre'/'pos' are empty */
#define luaC_checkGC(L) luaC_condGC(L,(void)0,(void)0)

View File

@ -1,8 +1,9 @@
/*
** $Id: ljumptab.h $
** Jump Table for the Lua interpreter
** See Copyright Notice in lua.h
*/
# 1 "./lua/ljumptab.h"
#undef vmdispatch

View File

@ -1,8 +1,9 @@
/*
** $Id: llex.h $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
# 1 "./lua/llex.h"
#ifndef llex_h
#define llex_h
@ -13,10 +14,10 @@
#include "lzio.h"
/*
** Single-char tokens (terminal symbols) are represented by their own
** numeric code. Other tokens start at the following value.
*/
#define FIRST_RESERVED (UCHAR_MAX + 1)
@ -25,24 +26,24 @@
#endif
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER RESERVED"
*/
enum RESERVED {
/* terminal symbols denoted by reserved words */
TK_AND = FIRST_RESERVED, TK_BREAK,
TK_DO, TK_ELSE, TK_ELSEIF, TK_END, TK_FALSE, TK_FOR, TK_FUNCTION,
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
TK_SHL, TK_SHR,
TK_DBCOLON, TK_EOS,
TK_FLT, TK_INT, TK_NAME, TK_STRING
};
/* number of reserved words */
#define NUM_RESERVED (cast_int(TK_WHILE-FIRST_RESERVED + 1))
@ -50,7 +51,7 @@ typedef union {
lua_Number r;
lua_Integer i;
TString *ts;
} SemInfo; /* semantics information */
} SemInfo;
typedef struct Token {
@ -59,22 +60,22 @@ typedef struct Token {
} Token;
/* state of the lexer plus state of the parser when shared by all
functions */
typedef struct LexState {
int current; /* current character (charint) */
int linenumber; /* input line counter */
int lastline; /* line of last token 'consumed' */
Token t; /* current token */
Token lookahead; /* look ahead token */
struct FuncState *fs; /* current function (parser) */
int current;
int linenumber;
int lastline;
Token t;
Token lookahead;
struct FuncState *fs;
struct lua_State *L;
ZIO *z; /* input stream */
Mbuffer *buff; /* buffer for tokens */
Table *h; /* to avoid collection/reuse strings */
struct Dyndata *dyd; /* dynamic structures used by the parser */
TString *source; /* current source name */
TString *envn; /* environment variable name */
ZIO *z;
Mbuffer *buff;
Table *h;
struct Dyndata *dyd;
TString *source;
TString *envn;
} LexState;

View File

@ -1,8 +1,9 @@
/*
** $Id: llimits.h $
** Limits, basic types, and some other 'installation-dependent' definitions
** See Copyright Notice in lua.h
*/
# 1 "./lua/llimits.h"
#ifndef llimits_h
#define llimits_h
@ -15,32 +16,32 @@
#include "lua.h"
/*
** 'lu_mem' and 'l_mem' are unsigned/signed integers big enough to count
** the total memory used by Lua (in bytes). Usually, 'size_t' and
** 'ptrdiff_t' should work, but we use 'long' for 16-bit machines.
*/
#if defined(LUAI_MEM) /* { external definitions? */
#if defined(LUAI_MEM)
typedef LUAI_UMEM lu_mem;
typedef LUAI_MEM l_mem;
#elif LUAI_IS32INT /* }{ */
#elif LUAI_IS32INT
typedef size_t lu_mem;
typedef ptrdiff_t l_mem;
#else /* 16-bit ints */ /* }{ */
#else
typedef unsigned long lu_mem;
typedef long l_mem;
#endif /* } */
#endif
/* chars used as small naturals (so that 'char' is reserved for characters) */
typedef unsigned char lu_byte;
typedef signed char ls_byte;
/* maximum value for size_t */
#define MAX_SIZET ((size_t)(~(size_t)0))
/* maximum size visible for Lua (must be representable in a lua_Integer) */
#define MAX_SIZE (sizeof(size_t) < sizeof(lua_Integer) ? MAX_SIZET \
: (size_t)(LUA_MAXINTEGER))
@ -50,43 +51,43 @@ typedef signed char ls_byte;
#define MAX_LMEM ((l_mem)(MAX_LUMEM >> 1))
#define MAX_INT INT_MAX /* maximum value of an int */
#define MAX_INT INT_MAX
/*
** floor of the log2 of the maximum signed value for integral type 't'.
** (That is, maximum 'n' such that '2^n' fits in the given signed type.)
*/
#define log2maxs(t) (sizeof(t) * 8 - 2)
/*
** test whether an unsigned value is a power of 2 (or zero)
*/
#define ispow2(x) (((x) & ((x) - 1)) == 0)
/* number of chars of a literal string without the ending \0 */
#define LL(x) (sizeof(x)/sizeof(char) - 1)
/*
** conversion of pointer to unsigned integer:
** this is for hashing only; there is no problem if the integer
** cannot hold the whole pointer value
*/
#define point2uint(p) ((unsigned int)((size_t)(p) & UINT_MAX))
/* types of 'usual argument conversions' for lua_Number and lua_Integer */
typedef LUAI_UACNUMBER l_uacNumber;
typedef LUAI_UACINT l_uacInt;
/*
** Internal assertions for in-house debugging
*/
#if defined LUAI_ASSERT
#undef NDEBUG
#include <assert.h>
@ -95,7 +96,7 @@ typedef LUAI_UACINT l_uacInt;
#if defined(lua_assert)
#define check_exp(c,e) (lua_assert(c), (e))
/* to avoid problems with conditions too long */
#define lua_longassert(c) ((c) ? (void)0 : lua_assert(0))
#else
#define lua_assert(c) ((void)0)
@ -103,9 +104,9 @@ typedef LUAI_UACINT l_uacInt;
#define lua_longassert(c) ((void)0)
#endif
/*
** assertion for checking API calls
*/
#if !defined(luai_apicheck)
#define luai_apicheck(l,e) ((void)l, lua_assert(e))
#endif
@ -113,13 +114,13 @@ typedef LUAI_UACINT l_uacInt;
#define api_check(l,e,msg) luai_apicheck(l,(e) && msg)
/* macro to avoid warnings about unused variables */
#if !defined(UNUSED)
#define UNUSED(x) ((void)(x))
#endif
/* type casts (a macro highlights casts in the code) */
#define cast(t,exp) ((t)(exp))
#define cast_void(i) cast(void, (i))
@ -134,24 +135,24 @@ typedef LUAI_UACINT l_uacInt;
#define cast_sizet(i) cast(size_t, (i))
/* cast a signed lua_Integer to lua_Unsigned */
#if !defined(l_castS2U)
#define l_castS2U(i) ((lua_Unsigned)(i))
#endif
/*
** cast a lua_Unsigned to a signed lua_Integer; this cast is
** not strict ISO C, but two-complement architectures should
** work fine.
*/
#if !defined(l_castU2S)
#define l_castU2S(i) ((lua_Integer)(i))
#endif
/*
** non-return type
*/
#if !defined(l_noret)
#if defined(__GNUC__)
@ -165,24 +166,24 @@ typedef LUAI_UACINT l_uacInt;
#endif
/*
** Inline functions
*/
#if !defined(LUA_USE_C89)
#define l_inline inline
#elif defined(__GNUC__)
#define l_inline __inline__
#else
#define l_inline /* empty */
#define l_inline
#endif
#define l_sinline static l_inline
/*
** type for virtual-machine instructions;
** must be an unsigned with (at least) 4 bytes (see details in lopcodes.h)
*/
#if LUAI_IS32INT
typedef unsigned int l_uint32;
#else
@ -190,81 +191,59 @@ typedef unsigned long l_uint32;
#endif
typedef l_uint32 Instruction;
/*
** Maximum length for short strings, that is, strings that are
** internalized. (Cannot be smaller than reserved words or tags for
** metamethods, as these strings must be internalized;
** #("function") = 8, #("__newindex") = 10.)
*/
# 202 "./lua/llimits.h"
#if !defined(LUAI_MAXSHORTLEN)
#define LUAI_MAXSHORTLEN 40
#endif
/*
** Initial size for the string table (must be power of 2).
** The Lua core alone registers ~50 strings (reserved words +
** metaevent keys + a few others). Libraries would typically add
** a few dozens more.
*/
# 213 "./lua/llimits.h"
#if !defined(MINSTRTABSIZE)
#define MINSTRTABSIZE 128
#endif
/*
** Size of cache for strings in the API. 'N' is the number of
** sets (better be a prime) and "M" is the size of each set (M == 1
** makes a direct cache.)
*/
#if !defined(STRCACHE_N)
#define STRCACHE_N 53
#define STRCACHE_M 2
#endif
/* minimum size for string buffer */
#if !defined(LUA_MINBUFFER)
#define LUA_MINBUFFER 32
#endif
/*
** Maximum depth for nested C calls, syntactical nested non-terminals,
** and other features implemented through recursion in C. (Value must
** fit in a 16-bit unsigned integer. It must also be compatible with
** the size of the C stack.)
*/
# 241 "./lua/llimits.h"
#if !defined(LUAI_MAXCCALLS)
#define LUAI_MAXCCALLS 200
#endif
/*
** macros that are executed whenever program enters the Lua core
** ('lua_lock') and leaves the core ('lua_unlock')
*/
#if !defined(lua_lock)
#define lua_lock(L) ((void) 0)
#define lua_unlock(L) ((void) 0)
#endif
/*
** macro executed during Lua functions at points where the
** function can yield.
*/
#if !defined(luai_threadyield)
#define luai_threadyield(L) {lua_unlock(L); lua_lock(L);}
#endif
/*
** these macros allow user-specific actions when a thread is
** created/deleted/resumed/yielded.
*/
#if !defined(luai_userstateopen)
#define luai_userstateopen(L) ((void)L)
#endif
@ -288,47 +267,29 @@ typedef l_uint32 Instruction;
#if !defined(luai_userstateyield)
#define luai_userstateyield(L,n) ((void)L)
#endif
/*
** The luai_num* macros define the primitive operations over numbers.
*/
/* floor division (defined as 'floor(a/b)') */
# 299 "./lua/llimits.h"
#if !defined(luai_numidiv)
#define luai_numidiv(L,a,b) ((void)L, l_floor(luai_numdiv(L,a,b)))
#endif
/* float division */
#if !defined(luai_numdiv)
#define luai_numdiv(L,a,b) ((a)/(b))
#endif
/*
** modulo: defined as 'a - floor(a/b)*b'; the direct computation
** using this definition has several problems with rounding errors,
** so it is better to use 'fmod'. 'fmod' gives the result of
** 'a - trunc(a/b)*b', and therefore must be corrected when
** 'trunc(a/b) ~= floor(a/b)'. That happens when the division has a
** non-integer negative result: non-integer result is equivalent to
** a non-zero remainder 'm'; negative result is equivalent to 'a' and
** 'b' with different signs, or 'm' and 'b' with different signs
** (as the result 'm' of 'fmod' has the same sign of 'a').
*/
# 319 "./lua/llimits.h"
#if !defined(luai_nummod)
#define luai_nummod(L,a,b,m) \
{ (void)L; (m) = l_mathop(fmod)(a,b); \
if (((m) > 0) ? (b) < 0 : ((m) < 0 && (b) > 0)) (m) += (b); }
#endif
/* exponentiation */
#if !defined(luai_numpow)
#define luai_numpow(L,a,b) \
((void)L, (b == 2) ? (a)*(a) : l_mathop(pow)(a,b))
#endif
/* the others are quite standard operations */
#if !defined(luai_numadd)
#define luai_numadd(L,a,b) ((a)+(b))
#define luai_numsub(L,a,b) ((a)-(b))
@ -341,18 +302,11 @@ typedef l_uint32 Instruction;
#define luai_numge(a,b) ((a)>=(b))
#define luai_numisnan(a) (!luai_numeq((a), (a)))
#endif
/*
** macro to control inclusion of some hard tests on stack reallocation
*/
# 352 "./lua/llimits.h"
#if !defined(HARDSTACKTESTS)
#define condmovestack(L,pre,pos) ((void)0)
#else
/* realloc stack keeping its size */
#define condmovestack(L,pre,pos) \
{ int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; }
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lmem.h $
** Interface to Memory Manager
** See Copyright Notice in lua.h
*/
# 1 "./lua/lmem.h"
#ifndef lmem_h
#define lmem_h
@ -15,40 +16,21 @@
#define luaM_error(L) luaD_throw(L, LUA_ERRMEM)
/*
** This macro tests whether it is safe to multiply 'n' by the size of
** type 't' without overflows. Because 'e' is always constant, it avoids
** the runtime division MAX_SIZET/(e).
** (The macro is somewhat complex to avoid warnings: The 'sizeof'
** comparison avoids a runtime comparison when overflow cannot occur.
** The compiler should be able to optimize the real test by itself, but
** when it does it, it may give a warning about "comparison is always
** false due to limited range of data type"; the +1 tricks the compiler,
** avoiding this warning but also this optimization.)
*/
# 31 "./lua/lmem.h"
#define luaM_testsize(n,e) \
(sizeof(n) >= sizeof(size_t) && cast_sizet((n)) + 1 > MAX_SIZET/(e))
#define luaM_checksize(L,n,e) \
(luaM_testsize(n,e) ? luaM_toobig(L) : cast_void(0))
/*
** Computes the minimum between 'n' and 'MAX_SIZET/sizeof(t)', so that
** the result is not larger than 'n' and cannot overflow a 'size_t'
** when multiplied by the size of type 't'. (Assumes that 'n' is an
** 'int' or 'unsigned int' and that 'int' is not larger than 'size_t'.)
*/
# 44 "./lua/lmem.h"
#define luaM_limitN(n,t) \
((cast_sizet(n) <= MAX_SIZET/sizeof(t)) ? (n) : \
cast_uint((MAX_SIZET/sizeof(t))))
/*
** Arrays of chars do not need any test
*/
#define luaM_reallocvchar(L,b,on,n) \
cast_charp(luaM_saferealloc_(L, (b), (on)*sizeof(char), (n)*sizeof(char)))
@ -76,7 +58,7 @@
LUAI_FUNC l_noret luaM_toobig (lua_State *L);
/* not to be called directly */
LUAI_FUNC void *luaM_realloc_ (lua_State *L, void *block, size_t oldsize,
size_t size);
LUAI_FUNC void *luaM_saferealloc_ (lua_State *L, void *block, size_t oldsize,
@ -90,4 +72,3 @@ LUAI_FUNC void *luaM_shrinkvector_ (lua_State *L, void *block, int *nelem,
LUAI_FUNC void *luaM_malloc_ (lua_State *L, size_t size, int tag);
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lobject.h $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
# 1 "./lua/lobject.h"
#ifndef lobject_h
@ -16,49 +17,40 @@
#include "lua.h"
/*
** Extra types for collectable non-values
*/
#define LUA_TUPVAL LUA_NUMTYPES /* upvalues */
#define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */
#define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */
/*
** number of all possible types (including LUA_TNONE but excluding DEADKEY)
*/
#define LUA_TUPVAL LUA_NUMTYPES
#define LUA_TPROTO (LUA_NUMTYPES+1)
#define LUA_TDEADKEY (LUA_NUMTYPES+2)
#define LUA_TOTALTYPES (LUA_TPROTO + 2)
/*
** tags for Tagged Values have the following use of bits:
** bits 0-3: actual tag (a LUA_T* constant)
** bits 4-5: variant bits
** bit 6: whether value is collectable
*/
/* add variant bits to a type */
# 42 "./lua/lobject.h"
#define makevariant(t,v) ((t) | ((v) << 4))
/*
** Union of all Lua values
*/
typedef union Value {
struct GCObject *gc; /* collectable objects */
void *p; /* light userdata */
lua_CFunction f; /* light C functions */
lua_Integer i; /* integer numbers */
lua_Number n; /* float numbers */
struct GCObject *gc;
void *p;
lua_CFunction f;
lua_Integer i;
lua_Number n;
} Value;
/*
** Tagged Values. This is the basic representation of values in Lua:
** an actual value plus a tag with its type.
*/
#define TValuefields Value value_; lu_byte tt_
@ -71,78 +63,69 @@ typedef struct TValue {
#define valraw(o) (val_(o))
/* raw type tag of a TValue */
#define rawtt(o) ((o)->tt_)
/* tag with no variants (bits 0-3) */
#define novariant(t) ((t) & 0x0F)
/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
#define withvariant(t) ((t) & 0x3F)
#define ttypetag(o) withvariant(rawtt(o))
/* type of a TValue */
#define ttype(o) (novariant(rawtt(o)))
/* Macros to test type */
#define checktag(o,t) (rawtt(o) == (t))
#define checktype(o,t) (ttype(o) == (t))
/* Macros for internal tests */
/* collectable object has the same tag as the original value */
#define righttt(obj) (ttypetag(obj) == gcvalue(obj)->tt)
/*
** Any value being manipulated by the program either is non
** collectable, or the collectable object has the right tag
** and it is not dead. The option 'L == NULL' allows other
** macros using this one to be used where L is not available.
*/
#define checkliveness(L,obj) \
((void)L, lua_longassert(!iscollectable(obj) || \
(righttt(obj) && (L == NULL || !isdead(G(L),gcvalue(obj))))))
/* Macros to set values */
/* set a value's tag */
#define settt_(o,t) ((o)->tt_=(t))
/* main macro to copy values (from 'obj2' to 'obj1') */
#define setobj(L,obj1,obj2) \
{ TValue *io1=(obj1); const TValue *io2=(obj2); \
io1->value_ = io2->value_; settt_(io1, io2->tt_); \
checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); }
/*
** Different types of assignments, according to source and destination.
** (They are mostly equal now, but may be different in the future.)
*/
/* from stack to stack */
#define setobjs2s(L,o1,o2) setobj(L,s2v(o1),s2v(o2))
/* to stack (not from same stack) */
#define setobj2s(L,o1,o2) setobj(L,s2v(o1),o2)
/* from table to same table */
#define setobjt2t setobj
/* to new object */
#define setobj2n setobj
/* to table */
#define setobj2t setobj
/*
** Entries in a Lua stack. Field 'tbclist' forms a list of all
** to-be-closed variables active in this stack. Dummy entries are
** used when the distance between two tbc variables does not fit
** in an unsigned short. They are represented by delta==0, and
** their real delta is always the maximum value that fits in
** that field.
*/
# 146 "./lua/lobject.h"
typedef union StackValue {
TValue val;
struct {
@ -152,35 +135,26 @@ typedef union StackValue {
} StackValue;
/* index to stack elements */
typedef StackValue *StkId;
/* convert a 'StackValue' to a 'TValue' */
#define s2v(o) (&(o)->val)
/*
** {==================================================================
** Nil
** ===================================================================
*/
/* Standard nil */
# 170 "./lua/lobject.h"
#define LUA_VNIL makevariant(LUA_TNIL, 0)
/* Empty slot (which might be different from a slot containing nil) */
#define LUA_VEMPTY makevariant(LUA_TNIL, 1)
/* Value returned for a key not found in a table (absent key) */
#define LUA_VABSTKEY makevariant(LUA_TNIL, 2)
/* macro to test for (any kind of) nil */
#define ttisnil(v) checktype((v), LUA_TNIL)
/* macro to test for a standard nil */
#define ttisstrictnil(o) checktag((o), LUA_VNIL)
@ -190,39 +164,27 @@ typedef StackValue *StkId;
#define isabstkey(v) checktag((v), LUA_VABSTKEY)
/*
** macro to detect non-standard nils (used only in assertions)
*/
#define isnonstrictnil(v) (ttisnil(v) && !ttisstrictnil(v))
/*
** By default, entries with any kind of nil are considered empty.
** (In any definition, values associated with absent keys must also
** be accepted as empty.)
*/
#define isempty(v) ttisnil(v)
/* macro defining a value corresponding to an absent key */
#define ABSTKEYCONSTANT {NULL}, LUA_VABSTKEY
/* mark an entry as empty */
#define setempty(v) settt_(v, LUA_VEMPTY)
/* }================================================================== */
/*
** {==================================================================
** Booleans
** ===================================================================
*/
# 226 "./lua/lobject.h"
#define LUA_VFALSE makevariant(LUA_TBOOLEAN, 0)
#define LUA_VTRUE makevariant(LUA_TBOOLEAN, 1)
@ -236,16 +198,7 @@ typedef StackValue *StkId;
#define setbfvalue(obj) settt_(obj, LUA_VFALSE)
#define setbtvalue(obj) settt_(obj, LUA_VTRUE)
/* }================================================================== */
/*
** {==================================================================
** Threads
** ===================================================================
*/
# 249 "./lua/lobject.h"
#define LUA_VTHREAD makevariant(LUA_TTHREAD, 0)
#define ttisthread(o) checktag((o), ctb(LUA_VTHREAD))
@ -258,35 +211,22 @@ typedef StackValue *StkId;
checkliveness(L,io); }
#define setthvalue2s(L,o,t) setthvalue(L,s2v(o),t)
/* }================================================================== */
/*
** {==================================================================
** Collectable Objects
** ===================================================================
*/
/*
** Common Header for all collectable objects (in macro form, to be
** included in other objects)
*/
# 275 "./lua/lobject.h"
#define CommonHeader struct GCObject *next; lu_byte tt; lu_byte marked
/* Common type for all collectable objects */
typedef struct GCObject {
CommonHeader;
} GCObject;
/* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 6)
#define iscollectable(o) (rawtt(o) & BIT_ISCOLLECTABLE)
/* mark a tag as collectable */
#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
@ -296,19 +236,9 @@ typedef struct GCObject {
#define setgcovalue(L,obj,x) \
{ TValue *io = (obj); GCObject *i_g=(x); \
val_(io).gc = i_g; settt_(io, ctb(i_g->tt)); }
/* }================================================================== */
/*
** {==================================================================
** Numbers
** ===================================================================
*/
/* Variant tags for numbers */
#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0) /* integer numbers */
#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1) /* float numbers */
# 310 "./lua/lobject.h"
#define LUA_VNUMINT makevariant(LUA_TNUMBER, 0)
#define LUA_VNUMFLT makevariant(LUA_TNUMBER, 1)
#define ttisnumber(o) checktype((o), LUA_TNUMBER)
#define ttisfloat(o) checktag((o), LUA_VNUMFLT)
@ -333,19 +263,9 @@ typedef struct GCObject {
#define chgivalue(obj,x) \
{ TValue *io=(obj); lua_assert(ttisinteger(io)); val_(io).i=(x); }
/* }================================================================== */
/*
** {==================================================================
** Strings
** ===================================================================
*/
/* Variant tags for strings */
#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0) /* short strings */
#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1) /* long strings */
# 347 "./lua/lobject.h"
#define LUA_VSHRSTR makevariant(LUA_TSTRING, 0)
#define LUA_VLNGSTR makevariant(LUA_TSTRING, 1)
#define ttisstring(o) checktype((o), LUA_TSTRING)
#define ttisshrstring(o) checktag((o), ctb(LUA_VSHRSTR))
@ -360,59 +280,45 @@ typedef struct GCObject {
val_(io).gc = obj2gco(x_); settt_(io, ctb(x_->tt)); \
checkliveness(L,io); }
/* set a string to the stack */
#define setsvalue2s(L,o,s) setsvalue(L,s2v(o),s)
/* set a string to a new object */
#define setsvalue2n setsvalue
/*
** Header for a string value.
*/
typedef struct TString {
CommonHeader;
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
lu_byte shrlen; /* length for short strings */
lu_byte extra;
lu_byte shrlen;
unsigned int hash;
union {
size_t lnglen; /* length for long strings */
struct TString *hnext; /* linked list for hash table */
size_t lnglen;
struct TString *hnext;
} u;
char contents[1];
} TString;
/*
** Get the actual string (array of bytes) from a 'TString'.
*/
#define getstr(ts) ((ts)->contents)
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(tsvalue(o))
/* get string length from 'TString *s' */
#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen)
/* get string length from 'TValue *o' */
#define vslen(o) tsslen(tsvalue(o))
/* }================================================================== */
/*
** {==================================================================
** Userdata
** ===================================================================
*/
/*
** Light userdata should be a variant of userdata, but for compatibility
** reasons they are also different types.
*/
# 416 "./lua/lobject.h"
#define LUA_VLIGHTUSERDATA makevariant(LUA_TLIGHTUSERDATA, 0)
#define LUA_VUSERDATA makevariant(LUA_TUSERDATA, 0)
@ -434,149 +340,110 @@ typedef struct TString {
checkliveness(L,io); }
/* Ensures that addresses after this type are always fully aligned. */
typedef union UValue {
TValue uv;
LUAI_MAXALIGN; /* ensures maximum alignment for udata bytes */
LUAI_MAXALIGN;
} UValue;
/*
** Header for userdata with user values;
** memory area follows the end of this structure.
*/
typedef struct Udata {
CommonHeader;
unsigned short nuvalue; /* number of user values */
size_t len; /* number of bytes */
unsigned short nuvalue;
size_t len;
struct Table *metatable;
GCObject *gclist;
UValue uv[1]; /* user values */
UValue uv[1];
} Udata;
/*
** Header for userdata with no user values. These userdata do not need
** to be gray during GC, and therefore do not need a 'gclist' field.
** To simplify, the code always use 'Udata' for both kinds of userdata,
** making sure it never accesses 'gclist' on userdata with no user values.
** This structure here is used only to compute the correct size for
** this representation. (The 'bindata' field in its end ensures correct
** alignment for binary data following this header.)
*/
# 467 "./lua/lobject.h"
typedef struct Udata0 {
CommonHeader;
unsigned short nuvalue; /* number of user values */
size_t len; /* number of bytes */
unsigned short nuvalue;
size_t len;
struct Table *metatable;
union {LUAI_MAXALIGN;} bindata;
} Udata0;
/* compute the offset of the memory area of a userdata */
#define udatamemoffset(nuv) \
((nuv) == 0 ? offsetof(Udata0, bindata) \
: offsetof(Udata, uv) + (sizeof(UValue) * (nuv)))
/* get the address of the memory block inside 'Udata' */
#define getudatamem(u) (cast_charp(u) + udatamemoffset((u)->nuvalue))
/* compute the size of a userdata */
#define sizeudata(nuv,nb) (udatamemoffset(nuv) + (nb))
/* }================================================================== */
/*
** {==================================================================
** Prototypes
** ===================================================================
*/
# 496 "./lua/lobject.h"
#define LUA_VPROTO makevariant(LUA_TPROTO, 0)
/*
** Description of an upvalue for function prototypes
*/
typedef struct Upvaldesc {
TString *name; /* upvalue name (for debug information) */
lu_byte instack; /* whether it is in stack (register) */
lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
lu_byte kind; /* kind of corresponding variable */
TString *name;
lu_byte instack;
lu_byte idx;
lu_byte kind;
} Upvaldesc;
/*
** Description of a local variable for function prototypes
** (used for debug information)
*/
typedef struct LocVar {
TString *varname;
int startpc; /* first point where variable is active */
int endpc; /* first point where variable is dead */
int startpc;
int endpc;
} LocVar;
/*
** Associates the absolute line source for a given instruction ('pc').
** The array 'lineinfo' gives, for each instruction, the difference in
** lines from the previous instruction. When that difference does not
** fit into a byte, Lua saves the absolute line for that instruction.
** (Lua also saves the absolute line periodically, to speed up the
** computation of a line number: we can use binary search in the
** absolute-line array, but we must traverse the 'lineinfo' array
** linearly to compute a line.)
*/
# 531 "./lua/lobject.h"
typedef struct AbsLineInfo {
int pc;
int line;
} AbsLineInfo;
/*
** Function Prototypes
*/
typedef struct Proto {
CommonHeader;
lu_byte numparams; /* number of fixed (named) parameters */
lu_byte numparams;
lu_byte is_vararg;
lu_byte maxstacksize; /* number of registers needed by this function */
int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of 'k' */
lu_byte maxstacksize;
int sizeupvalues;
int sizek;
int sizecode;
int sizelineinfo;
int sizep; /* size of 'p' */
int sizep;
int sizelocvars;
int sizeabslineinfo; /* size of 'abslineinfo' */
int linedefined; /* debug information */
int lastlinedefined; /* debug information */
TValue *k; /* constants used by the function */
Instruction *code; /* opcodes */
struct Proto **p; /* functions defined inside the function */
Upvaldesc *upvalues; /* upvalue information */
ls_byte *lineinfo; /* information about source lines (debug information) */
AbsLineInfo *abslineinfo; /* idem */
LocVar *locvars; /* information about local variables (debug information) */
TString *source; /* used for debug information */
int sizeabslineinfo;
int linedefined;
int lastlinedefined;
TValue *k;
Instruction *code;
struct Proto **p;
Upvaldesc *upvalues;
ls_byte *lineinfo;
AbsLineInfo *abslineinfo;
LocVar *locvars;
TString *source;
GCObject *gclist;
} Proto;
/* }================================================================== */
/*
** {==================================================================
** Functions
** ===================================================================
*/
# 573 "./lua/lobject.h"
#define LUA_VUPVAL makevariant(LUA_TUPVAL, 0)
/* Variant tags for functions */
#define LUA_VLCL makevariant(LUA_TFUNCTION, 0) /* Lua closure */
#define LUA_VLCF makevariant(LUA_TFUNCTION, 1) /* light C function */
#define LUA_VCCL makevariant(LUA_TFUNCTION, 2) /* C closure */
#define LUA_VLCL makevariant(LUA_TFUNCTION, 0)
#define LUA_VLCF makevariant(LUA_TFUNCTION, 1)
#define LUA_VCCL makevariant(LUA_TFUNCTION, 2)
#define ttisfunction(o) checktype(o, LUA_TFUNCTION)
#define ttisLclosure(o) checktag((o), ctb(LUA_VLCL))
@ -610,19 +477,19 @@ typedef struct Proto {
checkliveness(L,io); }
/*
** Upvalues for Lua closures
*/
typedef struct UpVal {
CommonHeader;
lu_byte tbc; /* true if it represents a to-be-closed variable */
TValue *v; /* points to stack or to its own value */
lu_byte tbc;
TValue *v;
union {
struct { /* (when open) */
struct UpVal *next; /* linked list */
struct {
struct UpVal *next;
struct UpVal **previous;
} open;
TValue value; /* the value (when closed) */
TValue value;
} u;
} UpVal;
@ -634,14 +501,14 @@ typedef struct UpVal {
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
TValue upvalue[1]; /* list of upvalues */
TValue upvalue[1];
} CClosure;
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
UpVal *upvals[1]; /* list of upvalues */
UpVal *upvals[1];
} LClosure;
@ -652,16 +519,7 @@ typedef union Closure {
#define getproto(o) (clLvalue(o)->p)
/* }================================================================== */
/*
** {==================================================================
** Tables
** ===================================================================
*/
# 665 "./lua/lobject.h"
#define LUA_VTABLE makevariant(LUA_TTABLE, 0)
#define ttistable(o) checktag((o), ctb(LUA_VTABLE))
@ -674,47 +532,31 @@ typedef union Closure {
checkliveness(L,io); }
#define sethvalue2s(L,o,h) sethvalue(L,s2v(o),h)
/*
** Nodes for Hash tables: A pack of two TValue's (key-value pairs)
** plus a 'next' field to link colliding entries. The distribution
** of the key's fields ('key_tt' and 'key_val') not forming a proper
** 'TValue' allows for a smaller size for 'Node' both in 4-byte
** and 8-byte alignments.
*/
# 686 "./lua/lobject.h"
typedef union Node {
struct NodeKey {
TValuefields; /* fields for value */
lu_byte key_tt; /* key type */
int next; /* for chaining */
Value key_val; /* key value */
TValuefields;
lu_byte key_tt;
int next;
Value key_val;
} u;
TValue i_val; /* direct access to node's value as a proper 'TValue' */
TValue i_val;
} Node;
/* copy a value into a key */
#define setnodekey(L,node,obj) \
{ Node *n_=(node); const TValue *io_=(obj); \
n_->u.key_val = io_->value_; n_->u.key_tt = io_->tt_; \
checkliveness(L,io_); }
/* copy a value from a key */
#define getnodekey(L,obj,node) \
{ TValue *io_=(obj); const Node *n_=(node); \
io_->value_ = n_->u.key_val; io_->tt_ = n_->u.key_tt; \
checkliveness(L,io_); }
/*
** About 'alimit': if 'isrealasize(t)' is true, then 'alimit' is the
** real size of 'array'. Otherwise, the real size of 'array' is the
** smallest power of two not smaller than 'alimit' (or zero iff 'alimit'
** is zero); 'alimit' is then used as a hint for #t.
*/
# 718 "./lua/lobject.h"
#define BITRAS (1 << 7)
#define isrealasize(t) (!((t)->flags & BITRAS))
#define setrealasize(t) ((t)->flags &= cast_byte(~BITRAS))
@ -723,20 +565,20 @@ typedef union Node {
typedef struct Table {
CommonHeader;
lu_byte flags; /* 1<<p means tagmethod(p) is not present */
lu_byte lsizenode; /* log2 of size of 'node' array */
unsigned int alimit; /* "limit" of 'array' array */
TValue *array; /* array part */
lu_byte flags;
lu_byte lsizenode;
unsigned int alimit;
TValue *array;
Node *node;
Node *lastfree; /* any free position is before this position */
Node *lastfree;
struct Table *metatable;
GCObject *gclist;
} Table;
/*
** Macros to manipulate keys inserted in nodes
*/
#define keytt(node) ((node)->u.key_tt)
#define keyval(node) ((node)->u.key_val)
@ -752,24 +594,10 @@ typedef struct Table {
#define gckey(n) (keyval(n).gc)
#define gckeyN(n) (keyiscollectable(n) ? gckey(n) : NULL)
/*
** Dead keys in tables have the tag DEADKEY but keep their original
** gcvalue. This distinguishes them from regular keys but allows them to
** be found when searched in a special way. ('next' needs that to find
** keys removed from a table during a traversal.)
*/
# 763 "./lua/lobject.h"
#define setdeadkey(node) (keytt(node) = LUA_TDEADKEY)
#define keyisdead(node) (keytt(node) == LUA_TDEADKEY)
/* }================================================================== */
/*
** 'module' operation for hashing (size is always a power of 2)
*/
# 773 "./lua/lobject.h"
#define lmod(s,size) \
(check_exp((size&(size-1))==0, (cast_int((s) & ((size)-1)))))
@ -778,7 +606,7 @@ typedef struct Table {
#define sizenode(t) (twoto((t)->lsizenode))
/* size of buffer for 'luaO_utf8esc' function */
#define UTF8BUFFSZ 8
LUAI_FUNC int luaO_utf8esc (char *buff, unsigned long x);
@ -797,4 +625,3 @@ LUAI_FUNC void luaO_chunkid (char *out, const char *source, size_t srclen);
#endif

View File

@ -1,40 +1,21 @@
/*
** $Id: lopcodes.h $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
# 1 "./lua/lopcodes.h"
#ifndef lopcodes_h
#define lopcodes_h
#include "llimits.h"
# 32 "./lua/lopcodes.h"
enum OpMode {iABC, iABx, iAsBx, iAx, isJ};
/*===========================================================================
We assume that instructions are unsigned 32-bit integers.
All instructions have an opcode in the first 7 bits.
Instructions can have the following formats:
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
iABC C(8) | B(8) |k| A(8) | Op(7) |
iABx Bx(17) | A(8) | Op(7) |
iAsBx sBx (signed)(17) | A(8) | Op(7) |
iAx Ax(25) | Op(7) |
isJ sJ(25) | Op(7) |
A signed argument is represented in excess K: the represented value is
the written unsigned value minus K, where K is half the maximum for the
corresponding unsigned argument.
===========================================================================*/
enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
/*
** size and position of opcode arguments.
*/
#define SIZE_C 8
#define SIZE_B 8
#define SIZE_Bx (SIZE_C + SIZE_B + 1)
@ -56,15 +37,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
#define POS_Ax POS_A
#define POS_sJ POS_A
/*
** limits for opcode arguments.
** we use (signed) 'int' to manipulate most arguments,
** so they must fit in ints.
*/
/* Check whether type 'int' has at least 'b' bits ('b' < 32) */
# 68 "./lua/lopcodes.h"
#define L_INTHASBITS(b) ((UINT_MAX >> ((b) - 1)) >= 1)
@ -74,7 +47,7 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
#define MAXARG_Bx MAX_INT
#endif
#define OFFSET_sBx (MAXARG_Bx>>1) /* 'sBx' is signed */
#define OFFSET_sBx (MAXARG_Bx>>1)
#if L_INTHASBITS(SIZE_Ax)
@ -101,15 +74,15 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
#define sC2int(i) ((i) - OFFSET_sC)
/* creates a mask with 'n' 1 bits at position 'p' */
#define MASK1(n,p) ((~((~(Instruction)0)<<(n)))<<(p))
/* creates a mask with 'n' 0 bits at position 'p' */
#define MASK0(n,p) (~MASK1(n,p))
/*
** the following macros help to manipulate instructions
*/
#define GET_OPCODE(i) (cast(OpCode, ((i)>>POS_OP) & MASK1(SIZE_OP,0)))
#define SET_OPCODE(i,o) ((i) = (((i)&MASK0(SIZE_OP,POS_OP)) | \
@ -171,213 +144,134 @@ enum OpMode {iABC, iABx, iAsBx, iAx, isJ}; /* basic instruction formats */
| (cast(Instruction, k) << POS_k))
#if !defined(MAXINDEXRK) /* (for debugging only) */
#if !defined(MAXINDEXRK)
#define MAXINDEXRK MAXARG_B
#endif
/*
** invalid register that fits in 8 bits
*/
#define NO_REG MAXARG_A
/*
** R[x] - register
** K[x] - constant (in constant table)
** RK(x) == if k(i) then K[x] else R[x]
*/
/*
** Grep "ORDER OP" if you change these enums. Opcodes marked with a (*)
** has extra descriptions in the notes after the enumeration.
*/
# 197 "./lua/lopcodes.h"
typedef enum {
/*----------------------------------------------------------------------
name args description
------------------------------------------------------------------------*/
OP_MOVE,/* A B R[A] := R[B] */
OP_LOADI,/* A sBx R[A] := sBx */
OP_LOADF,/* A sBx R[A] := (lua_Number)sBx */
OP_LOADK,/* A Bx R[A] := K[Bx] */
OP_LOADKX,/* A R[A] := K[extra arg] */
OP_LOADFALSE,/* A R[A] := false */
OP_LFALSESKIP,/*A R[A] := false; pc++ (*) */
OP_LOADTRUE,/* A R[A] := true */
OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */
OP_GETUPVAL,/* A B R[A] := UpValue[B] */
OP_SETUPVAL,/* A B UpValue[B] := R[A] */
OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:string] */
OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */
OP_GETI,/* A B C R[A] := R[B][C] */
OP_GETFIELD,/* A B C R[A] := R[B][K[C]:string] */
OP_SETTABUP,/* A B C UpValue[A][K[B]:string] := RK(C) */
OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */
OP_SETI,/* A B C R[A][B] := RK(C) */
OP_SETFIELD,/* A B C R[A][K[B]:string] := RK(C) */
OP_NEWTABLE,/* A B C k R[A] := {} */
OP_MOVE,
OP_LOADI,
OP_LOADF,
OP_LOADK,
OP_LOADKX,
OP_LOADFALSE,
OP_LFALSESKIP,
OP_LOADTRUE,
OP_LOADNIL,
OP_GETUPVAL,
OP_SETUPVAL,
OP_SELF,/* A B C R[A+1] := R[B]; R[A] := R[B][RK(C):string] */
OP_GETTABUP,
OP_GETTABLE,
OP_GETI,
OP_GETFIELD,
OP_ADDI,/* A B sC R[A] := R[B] + sC */
OP_SETTABUP,
OP_SETTABLE,
OP_SETI,
OP_SETFIELD,
OP_ADDK,/* A B C R[A] := R[B] + K[C]:number */
OP_SUBK,/* A B C R[A] := R[B] - K[C]:number */
OP_MULK,/* A B C R[A] := R[B] * K[C]:number */
OP_MODK,/* A B C R[A] := R[B] % K[C]:number */
OP_POWK,/* A B C R[A] := R[B] ^ K[C]:number */
OP_DIVK,/* A B C R[A] := R[B] / K[C]:number */
OP_IDIVK,/* A B C R[A] := R[B] // K[C]:number */
OP_NEWTABLE,
OP_BANDK,/* A B C R[A] := R[B] & K[C]:integer */
OP_BORK,/* A B C R[A] := R[B] | K[C]:integer */
OP_BXORK,/* A B C R[A] := R[B] ~ K[C]:integer */
OP_SELF,
OP_SHRI,/* A B sC R[A] := R[B] >> sC */
OP_SHLI,/* A B sC R[A] := sC << R[B] */
OP_ADDI,
OP_ADD,/* A B C R[A] := R[B] + R[C] */
OP_SUB,/* A B C R[A] := R[B] - R[C] */
OP_MUL,/* A B C R[A] := R[B] * R[C] */
OP_MOD,/* A B C R[A] := R[B] % R[C] */
OP_POW,/* A B C R[A] := R[B] ^ R[C] */
OP_DIV,/* A B C R[A] := R[B] / R[C] */
OP_IDIV,/* A B C R[A] := R[B] // R[C] */
OP_ADDK,
OP_SUBK,
OP_MULK,
OP_MODK,
OP_POWK,
OP_DIVK,
OP_IDIVK,
OP_BAND,/* A B C R[A] := R[B] & R[C] */
OP_BOR,/* A B C R[A] := R[B] | R[C] */
OP_BXOR,/* A B C R[A] := R[B] ~ R[C] */
OP_SHL,/* A B C R[A] := R[B] << R[C] */
OP_SHR,/* A B C R[A] := R[B] >> R[C] */
OP_BANDK,
OP_BORK,
OP_BXORK,
OP_MMBIN,/* A B C call C metamethod over R[A] and R[B] (*) */
OP_MMBINI,/* A sB C k call C metamethod over R[A] and sB */
OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */
OP_SHRI,
OP_SHLI,
OP_UNM,/* A B R[A] := -R[B] */
OP_BNOT,/* A B R[A] := ~R[B] */
OP_NOT,/* A B R[A] := not R[B] */
OP_LEN,/* A B R[A] := #R[B] (length operator) */
OP_ADD,
OP_SUB,
OP_MUL,
OP_MOD,
OP_POW,
OP_DIV,
OP_IDIV,
OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */
OP_BAND,
OP_BOR,
OP_BXOR,
OP_SHL,
OP_SHR,
OP_CLOSE,/* A close all upvalues >= R[A] */
OP_TBC,/* A mark variable A "to be closed" */
OP_JMP,/* sJ pc += sJ */
OP_EQ,/* A B k if ((R[A] == R[B]) ~= k) then pc++ */
OP_LT,/* A B k if ((R[A] < R[B]) ~= k) then pc++ */
OP_LE,/* A B k if ((R[A] <= R[B]) ~= k) then pc++ */
OP_MMBIN,
OP_MMBINI,
OP_MMBINK,
OP_EQK,/* A B k if ((R[A] == K[B]) ~= k) then pc++ */
OP_EQI,/* A sB k if ((R[A] == sB) ~= k) then pc++ */
OP_LTI,/* A sB k if ((R[A] < sB) ~= k) then pc++ */
OP_LEI,/* A sB k if ((R[A] <= sB) ~= k) then pc++ */
OP_GTI,/* A sB k if ((R[A] > sB) ~= k) then pc++ */
OP_GEI,/* A sB k if ((R[A] >= sB) ~= k) then pc++ */
OP_UNM,
OP_BNOT,
OP_NOT,
OP_LEN,
OP_TEST,/* A k if (not R[A] == k) then pc++ */
OP_TESTSET,/* A B k if (not R[B] == k) then pc++ else R[A] := R[B] (*) */
OP_CONCAT,
OP_CALL,/* A B C R[A], ... ,R[A+C-2] := R[A](R[A+1], ... ,R[A+B-1]) */
OP_TAILCALL,/* A B C k return R[A](R[A+1], ... ,R[A+B-1]) */
OP_CLOSE,
OP_TBC,
OP_JMP,
OP_EQ,
OP_LT,
OP_LE,
OP_RETURN,/* A B C k return R[A], ... ,R[A+B-2] (see note) */
OP_RETURN0,/* return */
OP_RETURN1,/* A return R[A] */
OP_EQK,
OP_EQI,
OP_LTI,
OP_LEI,
OP_GTI,
OP_GEI,
OP_FORLOOP,/* A Bx update counters; if loop continues then pc-=Bx; */
OP_FORPREP,/* A Bx <check values and prepare counters>;
if not to run then pc+=Bx+1; */
OP_TEST,
OP_TESTSET,
OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */
OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */
OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */
OP_CALL,
OP_TAILCALL,
OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */
OP_RETURN,
OP_RETURN0,
OP_RETURN1,
OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */
OP_FORLOOP,
OP_FORPREP,
OP_VARARG,/* A C R[A], R[A+1], ..., R[A+C-2] = vararg */
OP_VARARGPREP,/*A (adjust vararg parameters) */
OP_TFORPREP,
OP_TFORCALL,
OP_TFORLOOP,
OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
OP_SETLIST,
OP_CLOSURE,
OP_VARARG,
OP_VARARGPREP,
OP_EXTRAARG
} OpCode;
#define NUM_OPCODES ((int)(OP_EXTRAARG) + 1)
/*===========================================================================
Notes:
(*) Opcode OP_LFALSESKIP is used to convert a condition to a boolean
value, in a code equivalent to (not cond ? false : true). (It
produces false and skips the next instruction producing true.)
(*) Opcodes OP_MMBIN and variants follow each arithmetic and
bitwise opcode. If the operation succeeds, it skips this next
opcode. Otherwise, this opcode calls the corresponding metamethod.
(*) Opcode OP_TESTSET is used in short-circuit expressions that need
both to jump and to produce a value, such as (a = b or c).
(*) In OP_CALL, if (B == 0) then B = top - A. If (C == 0), then
'top' is set to last_result+1, so next open instruction (OP_CALL,
OP_RETURN*, OP_SETLIST) may use 'top'.
(*) In OP_VARARG, if (C == 0) then use actual number of varargs and
set top (like in OP_CALL with C == 0).
(*) In OP_RETURN, if (B == 0) then return up to 'top'.
(*) In OP_LOADKX and OP_NEWTABLE, the next instruction is always
OP_EXTRAARG.
(*) In OP_SETLIST, if (B == 0) then real B = 'top'; if k, then
real C = EXTRAARG _ C (the bits of EXTRAARG concatenated with the
bits of C).
(*) In OP_NEWTABLE, B is log2 of the hash size (which is always a
power of 2) plus 1, or zero for size zero. If not k, the array size
is C. Otherwise, the array size is EXTRAARG _ C.
(*) For comparisons, k specifies what condition the test should accept
(true or false).
(*) In OP_MMBINI/OP_MMBINK, k means the arguments were flipped
(the constant is the first operand).
(*) All 'skips' (pc++) assume that next instruction is a jump.
(*) In instructions OP_RETURN/OP_TAILCALL, 'k' specifies that the
function builds upvalues, which may need to be closed. C > 0 means
the function is vararg, so that its 'func' must be corrected before
returning; in this case, (C - 1) is its number of fixed parameters.
(*) In comparisons with an immediate operand, C signals whether the
original operand was a float. (It must be corrected in case of
metamethods.)
===========================================================================*/
/*
** masks for instruction properties. The format is:
** bits 0-2: op mode
** bit 3: instruction set register A
** bit 4: operator is a test (next instruction must be a jump)
** bit 5: instruction uses 'L->top' set by previous instruction (when B == 0)
** bit 6: instruction sets 'L->top' for next instruction (when C == 0)
** bit 7: instruction is an MM instruction (call a metamethod)
*/
# 381 "./lua/lopcodes.h"
LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];)
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 7))
@ -387,19 +281,19 @@ LUAI_DDEC(const lu_byte luaP_opmodes[NUM_OPCODES];)
#define testOTMode(m) (luaP_opmodes[m] & (1 << 6))
#define testMMMode(m) (luaP_opmodes[m] & (1 << 7))
/* "out top" (set top for next instruction) */
#define isOT(i) \
((testOTMode(GET_OPCODE(i)) && GETARG_C(i) == 0) || \
GET_OPCODE(i) == OP_TAILCALL)
/* "in top" (uses top from previous instruction) */
#define isIT(i) (testITMode(GET_OPCODE(i)) && GETARG_B(i) == 0)
#define opmode(mm,ot,it,t,a,m) \
(((mm) << 7) | ((ot) << 6) | ((it) << 5) | ((t) << 4) | ((a) << 3) | (m))
/* number of list items to accumulate before a SETLIST instruction */
#define LFIELDS_PER_FLUSH 50
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lopnames.h $
** Opcode names
** See Copyright Notice in lua.h
*/
# 1 "./lua/lopnames.h"
#if !defined(lopnames_h)
#define lopnames_h
@ -10,7 +11,7 @@
#include <stddef.h>
/* ORDER OP */
static const char *const opnames[] = {
"MOVE",
@ -100,4 +101,3 @@ static const char *const opnames[] = {
};
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lparser.h $
** Lua Parser
** See Copyright Notice in lua.h
*/
# 1 "./lua/lparser.h"
#ifndef lparser_h
#define lparser_h
@ -10,54 +11,43 @@
#include "llimits.h"
#include "lobject.h"
#include "lzio.h"
/*
** Expression and variable descriptor.
** Code generation for variables and expressions can be delayed to allow
** optimizations; An 'expdesc' structure describes a potentially-delayed
** variable/expression. It has a description of its "main" value plus a
** list of conditional jumps that can also produce its value (generated
** by short-circuit operators 'and'/'or').
*/
/* kinds of variables/expressions */
# 25 "./lua/lparser.h"
typedef enum {
VVOID, /* when 'expdesc' describes the last expression of a list,
this kind means an empty list (so, no expression) */
VNIL, /* constant nil */
VTRUE, /* constant true */
VFALSE, /* constant false */
VK, /* constant in 'k'; info = index of constant in 'k' */
VKFLT, /* floating constant; nval = numerical float value */
VKINT, /* integer constant; ival = numerical integer value */
VKSTR, /* string constant; strval = TString address;
(string is fixed by the lexer) */
VNONRELOC, /* expression has its value in a fixed register;
info = result register */
VLOCAL, /* local variable; var.ridx = register index;
var.vidx = relative index in 'actvar.arr' */
VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */
VCONST, /* compile-time <const> variable;
info = absolute index in 'actvar.arr' */
VINDEXED, /* indexed variable;
ind.t = table register;
ind.idx = key's R index */
VINDEXUP, /* indexed upvalue;
ind.t = table upvalue;
ind.idx = key's K index */
VINDEXI, /* indexed variable with constant integer;
ind.t = table register;
ind.idx = key's value */
VINDEXSTR, /* indexed variable with literal string;
ind.t = table register;
ind.idx = key's K index */
VJMP, /* expression is a test/comparison;
info = pc of corresponding jump instruction */
VRELOC, /* expression can put result in any register;
info = instruction pc */
VCALL, /* expression is a function call; info = instruction pc */
VVARARG /* vararg expression; info = instruction pc */
VVOID,
VNIL,
VTRUE,
VFALSE,
VK,
VKFLT,
VKINT,
VKSTR,
VNONRELOC,
VLOCAL,
VUPVAL,
VCONST,
VINDEXED,
VINDEXUP,
VINDEXI,
VINDEXSTR,
VJMP,
VRELOC,
VCALL,
VVARARG
} expkind;
@ -68,98 +58,98 @@ typedef enum {
typedef struct expdesc {
expkind k;
union {
lua_Integer ival; /* for VKINT */
lua_Number nval; /* for VKFLT */
TString *strval; /* for VKSTR */
int info; /* for generic use */
struct { /* for indexed variables */
short idx; /* index (R or "long" K) */
lu_byte t; /* table (register or upvalue) */
lua_Integer ival;
lua_Number nval;
TString *strval;
int info;
struct {
short idx;
lu_byte t;
} ind;
struct { /* for local variables */
lu_byte ridx; /* register holding the variable */
unsigned short vidx; /* compiler index (in 'actvar.arr') */
struct {
lu_byte ridx;
unsigned short vidx;
} var;
} u;
int t; /* patch list of 'exit when true' */
int f; /* patch list of 'exit when false' */
int t;
int f;
} expdesc;
/* kinds of variables */
#define VDKREG 0 /* regular */
#define RDKCONST 1 /* constant */
#define RDKTOCLOSE 2 /* to-be-closed */
#define RDKCTC 3 /* compile-time constant */
/* description of an active local variable */
#define VDKREG 0
#define RDKCONST 1
#define RDKTOCLOSE 2
#define RDKCTC 3
typedef union Vardesc {
struct {
TValuefields; /* constant value (if it is a compile-time constant) */
TValuefields;
lu_byte kind;
lu_byte ridx; /* register holding the variable */
short pidx; /* index of the variable in the Proto's 'locvars' array */
TString *name; /* variable name */
lu_byte ridx;
short pidx;
TString *name;
} vd;
TValue k; /* constant value (if any) */
TValue k;
} Vardesc;
/* description of pending goto statements and label statements */
typedef struct Labeldesc {
TString *name; /* label identifier */
int pc; /* position in code */
int line; /* line where it appeared */
lu_byte nactvar; /* number of active variables in that position */
lu_byte close; /* goto that escapes upvalues */
TString *name;
int pc;
int line;
lu_byte nactvar;
lu_byte close;
} Labeldesc;
/* list of labels or gotos */
typedef struct Labellist {
Labeldesc *arr; /* array */
int n; /* number of entries in use */
int size; /* array size */
Labeldesc *arr;
int n;
int size;
} Labellist;
/* dynamic structures used by the parser */
typedef struct Dyndata {
struct { /* list of all active local variables */
struct {
Vardesc *arr;
int n;
int size;
} actvar;
Labellist gt; /* list of pending gotos */
Labellist label; /* list of active labels */
Labellist gt;
Labellist label;
} Dyndata;
/* control of blocks */
struct BlockCnt; /* defined in lparser.c */
struct BlockCnt;
/* state needed to generate code for a given function */
typedef struct FuncState {
Proto *f; /* current function header */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to 'ncode') */
int lasttarget; /* 'label' of last 'jump label' */
int previousline; /* last line that was saved in 'lineinfo' */
int nk; /* number of elements in 'k' */
int np; /* number of elements in 'p' */
int nabslineinfo; /* number of elements in 'abslineinfo' */
int firstlocal; /* index of first local var (in Dyndata array) */
int firstlabel; /* index of first label (in 'dyd->label->arr') */
short ndebugvars; /* number of elements in 'f->locvars' */
lu_byte nactvar; /* number of active local variables */
lu_byte nups; /* number of upvalues */
lu_byte freereg; /* first free register */
lu_byte iwthabs; /* instructions issued since last absolute line info */
lu_byte needclose; /* function needs to close upvalues when returning */
Proto *f;
struct FuncState *prev;
struct LexState *ls;
struct BlockCnt *bl;
int pc;
int lasttarget;
int previousline;
int nk;
int np;
int nabslineinfo;
int firstlocal;
int firstlabel;
short ndebugvars;
lu_byte nactvar;
lu_byte nups;
lu_byte freereg;
lu_byte iwthabs;
lu_byte needclose;
} FuncState;

View File

@ -1,45 +1,45 @@
/*
** $Id: lprefix.h $
** Definitions for Lua code that must come before any other header file
** See Copyright Notice in lua.h
*/
# 1 "./lua/lprefix.h"
#ifndef lprefix_h
#define lprefix_h
/*
** Allows POSIX/XSI stuff
*/
#if !defined(LUA_USE_C89) /* { */
#if !defined(LUA_USE_C89)
#if !defined(_XOPEN_SOURCE)
#define _XOPEN_SOURCE 600
#elif _XOPEN_SOURCE == 0
#undef _XOPEN_SOURCE /* use -D_XOPEN_SOURCE=0 to undefine it */
#undef _XOPEN_SOURCE
#endif
/*
** Allows manipulation of large files in gcc and some other compilers
*/
#if !defined(LUA_32BITS) && !defined(_FILE_OFFSET_BITS)
#define _LARGEFILE_SOURCE 1
#define _FILE_OFFSET_BITS 64
#endif
#endif /* } */
#endif
/*
** Windows stuff
*/
#if defined(_WIN32) /* { */
#if defined(_WIN32)
#if !defined(_CRT_SECURE_NO_WARNINGS)
#define _CRT_SECURE_NO_WARNINGS /* avoid warnings about ISO C functions */
#define _CRT_SECURE_NO_WARNINGS
#endif
#endif /* } */
#endif
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lstate.h $
** Global State
** See Copyright Notice in lua.h
*/
# 1 "./lua/lstate.h"
#ifndef lstate_h
#define lstate_h
@ -12,128 +13,37 @@
#include "lobject.h"
#include "ltm.h"
#include "lzio.h"
/*
** Some notes about garbage-collected objects: All objects in Lua must
** be kept somehow accessible until being freed, so all objects always
** belong to one (and only one) of these lists, using field 'next' of
** the 'CommonHeader' for the link:
**
** 'allgc': all objects not marked for finalization;
** 'finobj': all objects marked for finalization;
** 'tobefnz': all objects ready to be finalized;
** 'fixedgc': all objects that are not to be collected (currently
** only small strings, such as reserved words).
**
** For the generational collector, some of these lists have marks for
** generations. Each mark points to the first element in the list for
** that particular generation; that generation goes until the next mark.
**
** 'allgc' -> 'survival': new objects;
** 'survival' -> 'old': objects that survived one collection;
** 'old1' -> 'reallyold': objects that became old in last collection;
** 'reallyold' -> NULL: objects old for more than one cycle.
**
** 'finobj' -> 'finobjsur': new objects marked for finalization;
** 'finobjsur' -> 'finobjold1': survived """";
** 'finobjold1' -> 'finobjrold': just old """";
** 'finobjrold' -> NULL: really old """".
**
** All lists can contain elements older than their main ages, due
** to 'luaC_checkfinalizer' and 'udata2finalize', which move
** objects between the normal lists and the "marked for finalization"
** lists. Moreover, barriers can age young objects in young lists as
** OLD0, which then become OLD1. However, a list never contains
** elements younger than their main ages.
**
** The generational collector also uses a pointer 'firstold1', which
** points to the first OLD1 object in the list. It is used to optimize
** 'markold'. (Potentially OLD1 objects can be anywhere between 'allgc'
** and 'reallyold', but often the list has no OLD1 objects or they are
** after 'old1'.) Note the difference between it and 'old1':
** 'firstold1': no OLD1 objects before this point; there can be all
** ages after it.
** 'old1': no objects younger than OLD1 after this point.
*/
/*
** Moreover, there is another set of lists that control gray objects.
** These lists are linked by fields 'gclist'. (All objects that
** can become gray have such a field. The field is not the same
** in all objects, but it always has this name.) Any gray object
** must belong to one of these lists, and all objects in these lists
** must be gray (with two exceptions explained below):
**
** 'gray': regular gray objects, still waiting to be visited.
** 'grayagain': objects that must be revisited at the atomic phase.
** That includes
** - black objects got in a write barrier;
** - all kinds of weak tables during propagation phase;
** - all threads.
** 'weak': tables with weak values to be cleared;
** 'ephemeron': ephemeron tables with white->white entries;
** 'allweak': tables with weak keys and/or weak values to be cleared.
**
** The exceptions to that "gray rule" are:
** - TOUCHED2 objects in generational mode stay in a gray list (because
** they must be visited again at the end of the cycle), but they are
** marked black because assignments to them must activate barriers (to
** move them back to TOUCHED1).
** - Open upvales are kept gray to avoid barriers, but they stay out
** of gray lists. (They don't even have a 'gclist' field.)
*/
/*
** About 'nCcalls': This count has two parts: the lower 16 bits counts
** the number of recursive invocations in the C stack; the higher
** 16 bits counts the number of non-yieldable calls in the stack.
** (They are together so that we can change and save both with one
** instruction.)
*/
/* true if this thread does not have non-yieldable calls in the stack */
# 99 "./lua/lstate.h"
#define yieldable(L) (((L)->nCcalls & 0xffff0000) == 0)
/* real number of C calls */
#define getCcalls(L) ((L)->nCcalls & 0xffff)
/* Increment the number of non-yieldable calls */
#define incnny(L) ((L)->nCcalls += 0x10000)
/* Decrement the number of non-yieldable calls */
#define decnny(L) ((L)->nCcalls -= 0x10000)
/* Non-yieldable call increment */
#define nyci (0x10000 | 1)
struct lua_longjmp; /* defined in ldo.c */
struct lua_longjmp;
/*
** Atomic type (relative to signals) to better ensure that 'lua_sethook'
** is thread safe
*/
#if !defined(l_signalT)
#include <signal.h>
#define l_signalT sig_atomic_t
#endif
/*
** Extra stack space to handle TM calls and some other extras. This
** space is not included in 'stack_last'. It is used only to avoid stack
** checks, either because the element will be promptly popped or because
** there will be a stack check soon after the push. Function frames
** never use this extra space, so it does not need to be kept clean.
*/
# 137 "./lua/lstate.h"
#define EXTRA_STACK 5
@ -142,185 +52,162 @@ struct lua_longjmp; /* defined in ldo.c */
#define stacksize(th) cast_int((th)->stack_last - (th)->stack)
/* kinds of Garbage Collection */
#define KGC_INC 0 /* incremental gc */
#define KGC_GEN 1 /* generational gc */
#define KGC_INC 0
#define KGC_GEN 1
typedef struct stringtable {
TString **hash;
int nuse; /* number of elements */
int nuse;
int size;
} stringtable;
/*
** Information about a call.
** About union 'u':
** - field 'l' is used only for Lua functions;
** - field 'c' is used only for C functions.
** About union 'u2':
** - field 'funcidx' is used only by C functions while doing a
** protected call;
** - field 'nyield' is used only while a function is "doing" an
** yield (from the yield until the next resume);
** - field 'nres' is used only while closing tbc variables when
** returning from a function;
** - field 'transferinfo' is used only during call/returnhooks,
** before the function starts or after it ends.
*/
# 172 "./lua/lstate.h"
typedef struct CallInfo {
StkId func; /* function index in the stack */
StkId top; /* top for this function */
struct CallInfo *previous, *next; /* dynamic call link */
StkId func;
StkId top;
struct CallInfo *previous, *next;
union {
struct { /* only for Lua functions */
struct {
const Instruction *savedpc;
volatile l_signalT trap;
int nextraargs; /* # of extra arguments in vararg functions */
int nextraargs;
} l;
struct { /* only for C functions */
lua_KFunction k; /* continuation in case of yields */
struct {
lua_KFunction k;
ptrdiff_t old_errfunc;
lua_KContext ctx; /* context info. in case of yields */
lua_KContext ctx;
} c;
} u;
union {
int funcidx; /* called-function index */
int nyield; /* number of values yielded */
int nres; /* number of values returned */
struct { /* info about transferred values (for call/return hooks) */
unsigned short ftransfer; /* offset of first value transferred */
unsigned short ntransfer; /* number of values transferred */
int funcidx;
int nyield;
int nres;
struct {
unsigned short ftransfer;
unsigned short ntransfer;
} transferinfo;
} u2;
short nresults; /* expected number of results from this function */
short nresults;
unsigned short callstatus;
} CallInfo;
/*
** Bits in CallInfo status
*/
#define CIST_OAH (1<<0) /* original value of 'allowhook' */
#define CIST_C (1<<1) /* call is running a C function */
#define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */
#define CIST_HOOKED (1<<3) /* call is running a debug hook */
#define CIST_YPCALL (1<<4) /* doing a yieldable protected call */
#define CIST_TAIL (1<<5) /* call was tail called */
#define CIST_HOOKYIELD (1<<6) /* last hook called yielded */
#define CIST_FIN (1<<7) /* function "called" a finalizer */
#define CIST_TRAN (1<<8) /* 'ci' has transfer information */
#define CIST_CLSRET (1<<9) /* function is closing tbc variables */
/* Bits 10-12 are used for CIST_RECST (see below) */
#define CIST_OAH (1<<0)
#define CIST_C (1<<1)
#define CIST_FRESH (1<<2)
#define CIST_HOOKED (1<<3)
#define CIST_YPCALL (1<<4)
#define CIST_TAIL (1<<5)
#define CIST_HOOKYIELD (1<<6)
#define CIST_FIN (1<<7)
#define CIST_TRAN (1<<8)
#define CIST_CLSRET (1<<9)
#define CIST_RECST 10
#if defined(LUA_COMPAT_LT_LE)
#define CIST_LEQ (1<<13) /* using __lt for __le */
#define CIST_LEQ (1<<13)
#endif
/*
** Field CIST_RECST stores the "recover status", used to keep the error
** status while closing to-be-closed variables in coroutines, so that
** Lua can correctly resume after an yield from a __close method called
** because of an error. (Three bits are enough for error status.)
*/
# 228 "./lua/lstate.h"
#define getcistrecst(ci) (((ci)->callstatus >> CIST_RECST) & 7)
#define setcistrecst(ci,st) \
check_exp(((st) & 7) == (st), /* status must fit in three bits */ \
check_exp(((st) & 7) == (st), \
((ci)->callstatus = ((ci)->callstatus & ~(7 << CIST_RECST)) \
| ((st) << CIST_RECST)))
/* active function is a Lua function */
#define isLua(ci) (!((ci)->callstatus & CIST_C))
/* call is running Lua code (not a hook) */
#define isLuacode(ci) (!((ci)->callstatus & (CIST_C | CIST_HOOKED)))
/* assume that CIST_OAH has offset 0 and that 'v' is strictly 0/1 */
#define setoah(st,v) ((st) = ((st) & ~CIST_OAH) | (v))
#define getoah(st) ((st) & CIST_OAH)
/*
** 'global state', shared by all threads of this state
*/
typedef struct global_State {
lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to 'frealloc' */
l_mem totalbytes; /* number of bytes currently allocated - GCdebt */
l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
lu_mem GCestimate; /* an estimate of the non-garbage memory in use */
lu_mem lastatomic; /* see function 'genstep' in file 'lgc.c' */
stringtable strt; /* hash table for strings */
lua_Alloc frealloc;
void *ud;
l_mem totalbytes;
l_mem GCdebt;
lu_mem GCestimate;
lu_mem lastatomic;
stringtable strt;
TValue l_registry;
TValue nilvalue; /* a nil value */
unsigned int seed; /* randomized seed for hashes */
TValue nilvalue;
unsigned int seed;
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
lu_byte gckind; /* kind of GC running */
lu_byte gcstopem; /* stops emergency collections */
lu_byte genminormul; /* control for minor generational collections */
lu_byte genmajormul; /* control for major generational collections */
lu_byte gcstp; /* control whether GC is running */
lu_byte gcemergency; /* true if this is an emergency collection */
lu_byte gcpause; /* size of pause between successive GCs */
lu_byte gcstepmul; /* GC "speed" */
lu_byte gcstepsize; /* (log2 of) GC granularity */
GCObject *allgc; /* list of all collectable objects */
GCObject **sweepgc; /* current position of sweep in list */
GCObject *finobj; /* list of collectable objects with finalizers */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
GCObject *weak; /* list of tables with weak values */
GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
GCObject *allweak; /* list of all-weak tables */
GCObject *tobefnz; /* list of userdata to be GC */
GCObject *fixedgc; /* list of objects not to be collected */
/* fields for generational collector */
GCObject *survival; /* start of objects that survived one GC cycle */
GCObject *old1; /* start of old1 objects */
GCObject *reallyold; /* objects more than one cycle old ("really old") */
GCObject *firstold1; /* first OLD1 object in the list (if any) */
GCObject *finobjsur; /* list of survival objects with finalizers */
GCObject *finobjold1; /* list of old1 objects with finalizers */
GCObject *finobjrold; /* list of really old objects with finalizers */
struct lua_State *twups; /* list of threads with open upvalues */
lua_CFunction panic; /* to be called in unprotected errors */
lu_byte gcstate;
lu_byte gckind;
lu_byte gcstopem;
lu_byte genminormul;
lu_byte genmajormul;
lu_byte gcstp;
lu_byte gcemergency;
lu_byte gcpause;
lu_byte gcstepmul;
lu_byte gcstepsize;
GCObject *allgc;
GCObject **sweepgc;
GCObject *finobj;
GCObject *gray;
GCObject *grayagain;
GCObject *weak;
GCObject *ephemeron;
GCObject *allweak;
GCObject *tobefnz;
GCObject *fixedgc;
GCObject *survival;
GCObject *old1;
GCObject *reallyold;
GCObject *firstold1;
GCObject *finobjsur;
GCObject *finobjold1;
GCObject *finobjrold;
struct lua_State *twups;
lua_CFunction panic;
struct lua_State *mainthread;
TString *memerrmsg; /* message for memory-allocation errors */
TString *tmname[TM_N]; /* array with tag-method names */
struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */
lua_WarnFunction warnf; /* warning function */
void *ud_warn; /* auxiliary data to 'warnf' */
TString *memerrmsg;
TString *tmname[TM_N];
struct Table *mt[LUA_NUMTAGS];
TString *strcache[STRCACHE_N][STRCACHE_M];
lua_WarnFunction warnf;
void *ud_warn;
} global_State;
/*
** 'per thread' state
*/
struct lua_State {
CommonHeader;
lu_byte status;
lu_byte allowhook;
unsigned short nci; /* number of items in 'ci' list */
StkId top; /* first free slot in the stack */
unsigned short nci;
StkId top;
global_State *l_G;
CallInfo *ci; /* call info for current function */
StkId stack_last; /* end of stack (last element + 1) */
StkId stack; /* stack base */
UpVal *openupval; /* list of open upvalues in this stack */
StkId tbclist; /* list of to-be-closed variables */
CallInfo *ci;
StkId stack_last;
StkId stack;
UpVal *openupval;
StkId tbclist;
GCObject *gclist;
struct lua_State *twups; /* list of threads with open upvalues */
struct lua_longjmp *errorJmp; /* current error recover point */
CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
struct lua_State *twups;
struct lua_longjmp *errorJmp;
CallInfo base_ci;
volatile lua_Hook hook;
ptrdiff_t errfunc; /* current error handling function (stack index) */
l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */
int oldpc; /* last pc traced */
ptrdiff_t errfunc;
l_uint32 nCcalls;
int oldpc;
int basehookcount;
int hookcount;
volatile l_signalT hookmask;
@ -329,42 +216,32 @@ struct lua_State {
#define G(L) (L->l_G)
/*
** 'g->nilvalue' being a nil value flags that the state was completely
** build.
*/
#define completestate(g) ttisnil(&g->nilvalue)
/*
** Union of all collectable objects (only for conversions)
** ISO C99, 6.5.2.3 p.5:
** "if a union contains several structures that share a common initial
** sequence [...], and if the union object currently contains one
** of these structures, it is permitted to inspect the common initial
** part of any of them anywhere that a declaration of the complete type
** of the union is visible."
*/
# 348 "./lua/lstate.h"
union GCUnion {
GCObject gc; /* common header */
GCObject gc;
struct TString ts;
struct Udata u;
union Closure cl;
struct Table h;
struct Proto p;
struct lua_State th; /* thread */
struct lua_State th;
struct UpVal upv;
};
/*
** ISO C99, 6.7.2.1 p.14:
** "A pointer to a union object, suitably converted, points to each of
** its members [...], and vice versa."
*/
#define cast_u(o) cast(union GCUnion *, (o))
/* macros to convert a GCObject into a specific value */
#define gco2ts(o) \
check_exp(novariant((o)->tt) == LUA_TSTRING, &((cast_u(o))->ts))
#define gco2u(o) check_exp((o)->tt == LUA_VUSERDATA, &((cast_u(o))->u))
@ -378,14 +255,14 @@ union GCUnion {
#define gco2upv(o) check_exp((o)->tt == LUA_VUPVAL, &((cast_u(o))->upv))
/*
** macro to convert a Lua object into a GCObject
** (The access to 'tt' tries to ensure that 'v' is actually a Lua object.)
*/
#define obj2gco(v) check_exp((v)->tt >= LUA_TSTRING, &(cast_u(v)->gc))
/* actual number of total bytes allocated */
#define gettotalbytes(g) cast(lu_mem, (g)->totalbytes + (g)->GCdebt)
LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
@ -401,4 +278,3 @@ LUAI_FUNC int luaE_resetthread (lua_State *L, int status);
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lstring.h $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
# 1 "./lua/lstring.h"
#ifndef lstring_h
#define lstring_h
@ -12,32 +13,32 @@
#include "lstate.h"
/*
** Memory-allocation error message must be preallocated (it cannot
** be created after memory is exhausted)
*/
#define MEMERRMSG "not enough memory"
/*
** Size of a TString: Size of the header plus space for the string
** itself (including final '\0').
*/
#define sizelstring(l) (offsetof(TString, contents) + ((l) + 1) * sizeof(char))
#define luaS_newliteral(L,s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
/*
** test whether a string is a reserved word
*/
#define isreserved(s) ((s)->tt == LUA_VSHRSTR && (s)->extra > 0)
/*
** equality for short strings, which are always internalized
*/
#define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b))

View File

@ -1,8 +1,9 @@
/*
** $Id: ltable.h $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
# 1 "./lua/ltable.h"
#ifndef ltable_h
#define ltable_h
@ -15,23 +16,23 @@
#define gnext(n) ((n)->u.next)
/*
** Clear all bits of fast-access metamethods, which means that the table
** may have any of these metamethods. (First access that fails after the
** clearing will set the bit again.)
*/
#define invalidateTMcache(t) ((t)->flags &= ~maskflags)
/* true when 't' is using 'dummynode' as its hash part */
#define isdummy(t) ((t)->lastfree == NULL)
/* allocated size for hash nodes */
#define allocsizenode(t) (isdummy(t) ? 0 : sizenode(t))
/* returns the Node, given the value of a table entry */
#define nodefromval(v) cast(Node *, (v))

View File

@ -1,8 +1,9 @@
/*
** $Id: ltm.h $
** Tag methods
** See Copyright Notice in lua.h
*/
# 1 "./lua/ltm.h"
#ifndef ltm_h
#define ltm_h
@ -11,17 +12,17 @@
#include "lobject.h"
/*
* WARNING: if you change the order of this enumeration,
* grep "ORDER TM" and "ORDER OP"
*/
typedef enum {
TM_INDEX,
TM_NEWINDEX,
TM_GC,
TM_MODE,
TM_LEN,
TM_EQ, /* last tag method with fast access */
TM_EQ,
TM_ADD,
TM_SUB,
TM_MUL,
@ -41,23 +42,16 @@ typedef enum {
TM_CONCAT,
TM_CALL,
TM_CLOSE,
TM_N /* number of elements in the enum */
TM_N
} TMS;
/*
** Mask with 1 in all fast-access methods. A 1 in any of these bits
** in the flag of a (meta)table means the metatable does not have the
** corresponding metamethod field. (Bit 7 of the flag is used for
** 'isrealasize'.)
*/
# 54 "./lua/ltm.h"
#define maskflags (~(~0u << (TM_EQ + 1)))
/*
** Test whether there is no tagmethod.
** (Because tagmethods use raw accesses, the result may be an "empty" nil.)
*/
#define notm(tm) ttisnil(tm)

View File

@ -1,11 +1,5 @@
/*
** $Id: lua.h $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
*/
# 1 "./lua/lua.h"
# 9 "./lua/lua.h"
#ifndef lua_h
#define lua_h
@ -29,23 +23,23 @@
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
/* mark for precompiled code ('<esc>Lua') */
#define LUA_SIGNATURE "\x1bLua"
/* option for multiple returns in 'lua_pcall' and 'lua_call' */
#define LUA_MULTRET (-1)
/*
** Pseudo-indices
** (-LUAI_MAXSTACK is the minimum valid index; we keep some free empty
** space after that to help overflow detection)
*/
#define LUA_REGISTRYINDEX (-LUAI_MAXSTACK - 1000)
#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
/* thread status */
#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
@ -57,9 +51,9 @@
typedef struct lua_State lua_State;
/*
** basic types
*/
#define LUA_TNONE (-1)
#define LUA_TNIL 0
@ -76,80 +70,80 @@ typedef struct lua_State lua_State;
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
/* predefined values in the registry */
#define LUA_RIDX_MAINTHREAD 1
#define LUA_RIDX_GLOBALS 2
#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
/* type of numbers in Lua */
typedef LUA_NUMBER lua_Number;
/* type for integer functions */
typedef LUA_INTEGER lua_Integer;
/* unsigned integer type */
typedef LUA_UNSIGNED lua_Unsigned;
/* type for continuation-function contexts */
typedef LUA_KCONTEXT lua_KContext;
/*
** Type for C functions registered with Lua
*/
typedef int (*lua_CFunction) (lua_State *L);
/*
** Type for continuation functions
*/
typedef int (*lua_KFunction) (lua_State *L, int status, lua_KContext ctx);
/*
** Type for functions that read/write blocks when loading/dumping Lua chunks
*/
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
/*
** Type for memory-allocation functions
*/
typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
/*
** Type for warning functions
*/
typedef void (*lua_WarnFunction) (void *ud, const char *msg, int tocont);
/*
** generic extra include file
*/
#if defined(LUA_USER_H)
#include LUA_USER_H
#endif
/*
** RCS ident string
*/
extern const char lua_ident[];
/*
** state manipulation
*/
LUA_API lua_State *(lua_newstate) (lua_Alloc f, void *ud);
LUA_API void (lua_close) (lua_State *L);
LUA_API lua_State *(lua_newthread) (lua_State *L);
@ -161,9 +155,9 @@ LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
LUA_API lua_Number (lua_version) (lua_State *L);
/*
** basic stack manipulation
*/
LUA_API int (lua_absindex) (lua_State *L, int idx);
LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
@ -175,9 +169,9 @@ LUA_API int (lua_checkstack) (lua_State *L, int n);
LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
/*
** access functions (stack -> C)
*/
LUA_API int (lua_isnumber) (lua_State *L, int idx);
LUA_API int (lua_isstring) (lua_State *L, int idx);
@ -198,11 +192,11 @@ LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
LUA_API const void *(lua_topointer) (lua_State *L, int idx);
/*
** Comparison and arithmetic functions
*/
#define LUA_OPADD 0 /* ORDER TM, ORDER OP */
#define LUA_OPADD 0
#define LUA_OPSUB 1
#define LUA_OPMUL 2
#define LUA_OPMOD 3
@ -227,9 +221,9 @@ LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
/*
** push functions (C -> stack)
*/
LUA_API void (lua_pushnil) (lua_State *L);
LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
@ -244,9 +238,9 @@ LUA_API void (lua_pushlightuserdata) (lua_State *L, void *p);
LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
LUA_API int (lua_getglobal) (lua_State *L, const char *name);
LUA_API int (lua_gettable) (lua_State *L, int idx);
LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
@ -261,9 +255,9 @@ LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
LUA_API int (lua_getiuservalue) (lua_State *L, int idx, int n);
/*
** set functions (stack -> Lua)
*/
LUA_API void (lua_setglobal) (lua_State *L, const char *name);
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
@ -275,9 +269,9 @@ LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
LUA_API int (lua_setiuservalue) (lua_State *L, int idx, int n);
/*
** 'load' and 'call' functions (load and run Lua code)
*/
LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults,
lua_KContext ctx, lua_KFunction k);
#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
@ -292,9 +286,9 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
/*
** coroutine functions
*/
LUA_API int (lua_yieldk) (lua_State *L, int nresults, lua_KContext ctx,
lua_KFunction k);
LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg,
@ -305,16 +299,16 @@ LUA_API int (lua_isyieldable) (lua_State *L);
#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
/*
** Warning-related functions
*/
LUA_API void (lua_setwarnf) (lua_State *L, lua_WarnFunction f, void *ud);
LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont);
/*
** garbage-collection function and options
*/
#define LUA_GCSTOP 0
#define LUA_GCRESTART 1
@ -331,9 +325,9 @@ LUA_API void (lua_warning) (lua_State *L, const char *msg, int tocont);
LUA_API int (lua_gc) (lua_State *L, int what, ...);
/*
** miscellaneous functions
*/
LUA_API int (lua_error) (lua_State *L);
@ -349,14 +343,7 @@ LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
LUA_API void (lua_toclose) (lua_State *L, int idx);
LUA_API void (lua_closeslot) (lua_State *L, int idx);
/*
** {==============================================================
** some useful macros
** ===============================================================
*/
# 360 "./lua/lua.h"
#define lua_getextraspace(L) ((void *)((char *)(L) - LUA_EXTRASPACE))
#define lua_tonumber(L,i) lua_tonumberx(L,(i),NULL)
@ -392,15 +379,7 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx);
#define lua_remove(L,idx) (lua_rotate(L, (idx), -1), lua_pop(L, 1))
#define lua_replace(L,idx) (lua_copy(L, -1, (idx)), lua_pop(L, 1))
/* }============================================================== */
/*
** {==============================================================
** compatibility macros
** ===============================================================
*/
# 404 "./lua/lua.h"
#if defined(LUA_COMPAT_APIINTCASTS)
#define lua_pushunsigned(L,n) lua_pushinteger(L, (lua_Integer)(n))
@ -414,19 +393,7 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx);
#define lua_setuservalue(L,idx) lua_setiuservalue(L,idx,1)
#define LUA_NUMTAGS LUA_NUMTYPES
/* }============================================================== */
/*
** {======================================================================
** Debug API
** =======================================================================
*/
/*
** Event codes
*/
# 430 "./lua/lua.h"
#define LUA_HOOKCALL 0
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
@ -434,18 +401,18 @@ LUA_API void (lua_closeslot) (lua_State *L, int idx);
#define LUA_HOOKTAILCALL 4
/*
** Event masks
*/
#define LUA_MASKCALL (1 << LUA_HOOKCALL)
#define LUA_MASKRET (1 << LUA_HOOKRET)
#define LUA_MASKLINE (1 << LUA_HOOKLINE)
#define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
typedef struct lua_Debug lua_Debug; /* activation record */
typedef struct lua_Debug lua_Debug;
/* Functions to be called by the debugger in specific events */
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
@ -469,50 +436,23 @@ LUA_API int (lua_setcstacklimit) (lua_State *L, unsigned int limit);
struct lua_Debug {
int event;
const char *name; /* (n) */
const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
const char *source; /* (S) */
size_t srclen; /* (S) */
int currentline; /* (l) */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
unsigned char nups; /* (u) number of upvalues */
unsigned char nparams;/* (u) number of parameters */
char isvararg; /* (u) */
char istailcall; /* (t) */
unsigned short ftransfer; /* (r) index of first value transferred */
unsigned short ntransfer; /* (r) number of transferred values */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
struct CallInfo *i_ci; /* active function */
const char *name;
const char *namewhat;
const char *what;
const char *source;
size_t srclen;
int currentline;
int linedefined;
int lastlinedefined;
unsigned char nups;
unsigned char nparams;
char isvararg;
char istailcall;
unsigned short ftransfer;
unsigned short ntransfer;
char short_src[LUA_IDSIZE];
struct CallInfo *i_ci;
};
/* }====================================================================== */
/******************************************************************************
* Copyright (C) 1994-2022 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.
******************************************************************************/
# 518 "./lua/lua.h"
#endif

View File

@ -1,6 +1,3 @@
// lua.hpp
// Lua header files for C++
// <<extern "C">> not supplied automatically because Lua also compiles as C++
extern "C" {
#include "lua.h"

View File

@ -1,8 +1,9 @@
/*
** $Id: luaconf.h $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
# 1 "./lua/luaconf.h"
#ifndef luaconf_h
@ -10,120 +11,61 @@
#include <limits.h>
#include <stddef.h>
/*
** ===================================================================
** General Configuration File for Lua
**
** Some definitions here can be changed externally, through the compiler
** (e.g., with '-D' options): They are commented out or protected
** by '#if !defined' guards. However, several other definitions
** should be changed directly here, either because they affect the
** Lua ABI (by making the changes here, you ensure that all software
** connected to Lua, such as C libraries, will be compiled with the same
** configuration); or because they are seldom changed.
**
** Search for "@@" to find all configurable definitions.
** ===================================================================
*/
/*
** {====================================================================
** System Configuration: macros to adapt (if needed) Lua to some
** particular platform, for instance restricting it to C89.
** =====================================================================
*/
/*
@@ LUA_USE_C89 controls the use of non-ISO-C89 features.
** Define it if you want Lua to avoid the use of a few C99 features
** or Windows-specific features on Windows.
*/
/* #define LUA_USE_C89 */
/*
** By default, Lua on Windows use (some) specific Windows features
*/
# 50 "./lua/luaconf.h"
#if !defined(LUA_USE_C89) && defined(_WIN32) && !defined(_WIN32_WCE)
#define LUA_USE_WINDOWS /* enable goodies for regular Windows */
#define LUA_USE_WINDOWS
#endif
#if defined(LUA_USE_WINDOWS)
#define LUA_DL_DLL /* enable support for DLL */
#define LUA_USE_C89 /* broadly, Windows is C89 */
#define LUA_DL_DLL
#define LUA_USE_C89
#endif
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#define LUA_USE_DLOPEN
#endif
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* MacOS does not need -ldl */
#define LUA_USE_DLOPEN
#endif
/*
@@ LUAI_IS32INT is true iff 'int' has (at least) 32 bits.
*/
#define LUAI_IS32INT ((UINT_MAX >> 30) >= 3)
/* }================================================================== */
/*
** {==================================================================
** Configuration for Number types. These options should not be
** set externally, because any other code connected to Lua must
** use the same configuration.
** ===================================================================
*/
/*
@@ LUA_INT_TYPE defines the type for Lua integers.
@@ LUA_FLOAT_TYPE defines the type for Lua floats.
** Lua should work fine with any mix of these options supported
** by your C compiler. The usual configurations are 64-bit integers
** and 'double' (the default), 32-bit integers and 'float' (for
** restricted platforms), and 'long'/'double' (for C compilers not
** compliant with C99, which may not have support for 'long long').
*/
/* predefined options for LUA_INT_TYPE */
# 101 "./lua/luaconf.h"
#define LUA_INT_INT 1
#define LUA_INT_LONG 2
#define LUA_INT_LONGLONG 3
/* predefined options for LUA_FLOAT_TYPE */
#define LUA_FLOAT_FLOAT 1
#define LUA_FLOAT_DOUBLE 2
#define LUA_FLOAT_LONGDOUBLE 3
/* Default configuration ('long long' and 'double', for 64-bit Lua) */
#define LUA_INT_DEFAULT LUA_INT_LONGLONG
#define LUA_FLOAT_DEFAULT LUA_FLOAT_DOUBLE
/*
@@ LUA_32BITS enables Lua with 32-bit integers and 32-bit floats.
*/
#define LUA_32BITS 0
/*
@@ LUA_C89_NUMBERS ensures that Lua uses the largest types available for
** C89 ('long' and 'double'); Windows always has '__int64', so it does
** not need to use this case.
*/
#if defined(LUA_USE_C89) && !defined(LUA_USE_WINDOWS)
#define LUA_C89_NUMBERS 1
#else
@ -131,71 +73,42 @@
#endif
#if LUA_32BITS /* { */
/*
** 32-bit integers and 'float'
*/
#if LUAI_IS32INT /* use 'int' if big enough */
#if LUA_32BITS
#if LUAI_IS32INT
#define LUA_INT_TYPE LUA_INT_INT
#else /* otherwise use 'long' */
#else
#define LUA_INT_TYPE LUA_INT_LONG
#endif
#define LUA_FLOAT_TYPE LUA_FLOAT_FLOAT
#elif LUA_C89_NUMBERS /* }{ */
/*
** largest types available for C89 ('long' and 'double')
*/
#elif LUA_C89_NUMBERS
#define LUA_INT_TYPE LUA_INT_LONG
#define LUA_FLOAT_TYPE LUA_FLOAT_DOUBLE
#else /* }{ */
/* use defaults */
#else
#define LUA_INT_TYPE LUA_INT_DEFAULT
#define LUA_FLOAT_TYPE LUA_FLOAT_DEFAULT
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for Paths.
** ===================================================================
*/
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
#endif
# 178 "./lua/luaconf.h"
#define LUA_PATH_SEP ";"
#define LUA_PATH_MARK "?"
#define LUA_EXEC_DIR "!"
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.
@@ LUA_CPATH_DEFAULT is the default path that Lua uses to look for
** C libraries.
** CHANGE them if your machine has a non-conventional directory
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
# 193 "./lua/luaconf.h"
#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#if defined(_WIN32) /* { */
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
*/
#if defined(_WIN32)
#define LUA_LDIR "!\\lua\\"
#define LUA_CDIR "!\\"
#define LUA_SHRDIR "!\\..\\share\\lua\\" LUA_VDIR "\\"
@ -215,7 +128,7 @@
LUA_CDIR"loadall.dll;" ".\\?.dll"
#endif
#else /* }{ */
#else
#define LUA_ROOT "/usr/local/"
#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR "/"
@ -233,14 +146,14 @@
LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
#endif
#endif /* } */
#endif
/*
@@ LUA_DIRSEP is the directory separator (for submodules).
** CHANGE it if your machine does not use "/" as the directory separator
** and is not Windows. (On Windows Lua automatically uses "\".)
*/
#if !defined(LUA_DIRSEP)
#if defined(_WIN32)
@ -250,119 +163,57 @@
#endif
#endif
# 272 "./lua/luaconf.h"
#if defined(LUA_BUILD_AS_DLL)
/* }================================================================== */
/*
** {==================================================================
** Marks for exported symbols in the C code
** ===================================================================
*/
/*
@@ LUA_API is a mark for all core API functions.
@@ LUALIB_API is a mark for all auxiliary library functions.
@@ LUAMOD_API is a mark for all standard library opening functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
#if defined(LUA_BUILD_AS_DLL) /* { */
#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
#if defined(LUA_CORE) || defined(LUA_LIB)
#define LUA_API __declspec(dllexport)
#else /* }{ */
#else
#define LUA_API __declspec(dllimport)
#endif /* } */
#endif
#else /* }{ */
#else
#define LUA_API extern
#endif /* } */
#endif
/*
** More often than not the libs go together with the core.
*/
#define LUALIB_API LUA_API
#define LUAMOD_API LUA_API
/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
** exported to outside modules.
@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables,
** none of which to be exported to outside modules (LUAI_DDEF for
** definitions and LUAI_DDEC for declarations).
** CHANGE them if you need to mark them in some special way. Elf/gcc
** (versions 3.2 and later) mark them as "hidden" to optimize access
** when Lua is compiled as a shared library. Not all elf targets support
** this attribute. Unfortunately, gcc does not offer a way to check
** whether the target offers that support, and those without support
** give a warning about it. To avoid these warnings, change to the
** default definition.
*/
# 308 "./lua/luaconf.h"
#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
defined(__ELF__) /* { */
defined(__ELF__)
#define LUAI_FUNC __attribute__((visibility("internal"))) extern
#else /* }{ */
#else
#define LUAI_FUNC extern
#endif /* } */
#endif
#define LUAI_DDEC(dec) LUAI_FUNC dec
#define LUAI_DDEF /* empty */
/* }================================================================== */
#define LUAI_DDEF
# 332 "./lua/luaconf.h"
#if defined(LUA_COMPAT_5_3)
/*
** {==================================================================
** Compatibility with previous versions
** ===================================================================
*/
/*
@@ LUA_COMPAT_5_3 controls other macros for compatibility with Lua 5.3.
** You can define it to get all options, or change specific options
** to fit your specific needs.
*/
#if defined(LUA_COMPAT_5_3) /* { */
/*
@@ LUA_COMPAT_MATHLIB controls the presence of several deprecated
** functions in the mathematical library.
** (These functions were already officially removed in 5.3;
** nevertheless they are still available here.)
*/
#define LUA_COMPAT_MATHLIB
/*
@@ LUA_COMPAT_APIINTCASTS controls the presence of macros for
** manipulating other integer types (lua_pushunsigned, lua_tounsigned,
** luaL_checkint, luaL_checklong, etc.)
** (These macros were also officially removed in 5.3, but they are still
** available here.)
*/
# 349 "./lua/luaconf.h"
#define LUA_COMPAT_APIINTCASTS
/*
@@ LUA_COMPAT_LT_LE controls the emulation of the '__le' metamethod
** using '__lt'.
*/
#define LUA_COMPAT_LT_LE
/*
@@ The following macros supply trivial compatibility for some
** changes in the API. The macros themselves document how to
** change your code to avoid using them.
** (Once more, these macros were officially removed in 5.3, but they are
** still available here.)
*/
# 366 "./lua/luaconf.h"
#define lua_strlen(L,i) lua_rawlen(L, (i))
#define lua_objlen(L,i) lua_rawlen(L, (i))
@ -370,59 +221,22 @@
#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Configuration for Numbers (low-level part).
** Change these definitions if no predefined LUA_FLOAT_* / LUA_INT_*
** satisfy your needs.
** ===================================================================
*/
/*
@@ LUAI_UACNUMBER is the result of a 'default argument promotion'
@@ over a floating number.
@@ l_floatatt(x) corrects float attribute 'x' to the proper float type
** by prefixing it with one of FLT/DBL/LDBL.
@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
@@ LUA_NUMBER_FMT is the format for writing floats.
@@ lua_number2str converts a float to a string.
@@ l_mathop allows the addition of an 'l' or 'f' to all math operations.
@@ l_floor takes the floor of a float.
@@ lua_str2number converts a decimal numeral to a number.
*/
/* The following definitions are good for most cases here */
#endif
# 403 "./lua/luaconf.h"
#define l_floor(x) (l_mathop(floor)(x))
#define lua_number2str(s,sz,n) \
l_sprintf((s), sz, LUA_NUMBER_FMT, (LUAI_UACNUMBER)(n))
/*
@@ lua_numbertointeger converts a float number with an integral value
** to an integer, or returns 0 if float is not within the range of
** a lua_Integer. (The range comparisons are tricky because of
** rounding. The tests here assume a two-complement representation,
** where MININTEGER always has an exact representation as a float;
** MAXINTEGER may not have one, and therefore its conversion to float
** may have an ill-defined value.)
*/
# 417 "./lua/luaconf.h"
#define lua_numbertointeger(n,p) \
((n) >= (LUA_NUMBER)(LUA_MININTEGER) && \
(n) < -(LUA_NUMBER)(LUA_MININTEGER) && \
(*(p) = (LUA_INTEGER)(n), 1))
/* now the variable definitions */
#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT /* { single float */
#if LUA_FLOAT_TYPE == LUA_FLOAT_FLOAT
#define LUA_NUMBER float
@ -438,7 +252,7 @@
#define lua_str2number(s,p) strtof((s), (p))
#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE /* }{ long double */
#elif LUA_FLOAT_TYPE == LUA_FLOAT_LONGDOUBLE
#define LUA_NUMBER long double
@ -453,7 +267,7 @@
#define lua_str2number(s,p) strtold((s), (p))
#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE /* }{ double */
#elif LUA_FLOAT_TYPE == LUA_FLOAT_DOUBLE
#define LUA_NUMBER double
@ -468,29 +282,12 @@
#define lua_str2number(s,p) strtod((s), (p))
#else /* }{ */
#else
#error "numeric float type not defined"
#endif /* } */
/*
@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
@@ LUAI_UACINT is the result of a 'default argument promotion'
@@ over a LUA_INTEGER.
@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
@@ LUA_INTEGER_FMT is the format for writing integers.
@@ LUA_MAXINTEGER is the maximum value for a LUA_INTEGER.
@@ LUA_MININTEGER is the minimum value for a LUA_INTEGER.
@@ LUA_MAXUNSIGNED is the maximum value for a LUA_UNSIGNED.
@@ lua_integer2str converts an integer to a string.
*/
/* The following definitions are good for most cases here */
#endif
# 494 "./lua/luaconf.h"
#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
#define LUAI_UACINT LUA_INTEGER
@ -498,16 +295,16 @@
#define lua_integer2str(s,sz,n) \
l_sprintf((s), sz, LUA_INTEGER_FMT, (LUAI_UACINT)(n))
/*
** use LUAI_UACINT here to avoid problems with promotions (which
** can turn a comparison between unsigneds into a signed comparison)
*/
#define LUA_UNSIGNED unsigned LUAI_UACINT
/* now the variable definitions */
#if LUA_INT_TYPE == LUA_INT_INT /* { int */
#if LUA_INT_TYPE == LUA_INT_INT
#define LUA_INTEGER int
#define LUA_INTEGER_FRMLEN ""
@ -517,7 +314,7 @@
#define LUA_MAXUNSIGNED UINT_MAX
#elif LUA_INT_TYPE == LUA_INT_LONG /* }{ long */
#elif LUA_INT_TYPE == LUA_INT_LONG
#define LUA_INTEGER long
#define LUA_INTEGER_FRMLEN "l"
@ -527,11 +324,11 @@
#define LUA_MAXUNSIGNED ULONG_MAX
#elif LUA_INT_TYPE == LUA_INT_LONGLONG /* }{ long long */
#elif LUA_INT_TYPE == LUA_INT_LONGLONG
#if defined(LLONG_MAX)
/* use presence of macro LLONG_MAX as proxy for C99 compliance */
#if defined(LLONG_MAX) /* { */
/* use ISO C99 stuff */
#define LUA_INTEGER long long
#define LUA_INTEGER_FRMLEN "ll"
@ -541,8 +338,8 @@
#define LUA_MAXUNSIGNED ULLONG_MAX
#elif defined(LUA_USE_WINDOWS) /* }{ */
/* in Windows, can use specific Windows types */
#elif defined(LUA_USE_WINDOWS)
#define LUA_INTEGER __int64
#define LUA_INTEGER_FRMLEN "I64"
@ -552,117 +349,69 @@
#define LUA_MAXUNSIGNED _UI64_MAX
#else /* }{ */
#else
#error "Compiler does not support 'long long'. Use option '-DLUA_32BITS' \
or '-DLUA_C89_NUMBERS' (see file 'luaconf.h' for details)"
#endif /* } */
#endif
#else /* }{ */
#else
#error "numeric integer type not defined"
#endif /* } */
/* }================================================================== */
/*
** {==================================================================
** Dependencies with C99 and other C details
** ===================================================================
*/
/*
@@ l_sprintf is equivalent to 'snprintf' or 'sprintf' in C89.
** (All uses in Lua have only one format item.)
*/
#endif
# 581 "./lua/luaconf.h"
#if !defined(LUA_USE_C89)
#define l_sprintf(s,sz,f,i) snprintf(s,sz,f,i)
#else
#define l_sprintf(s,sz,f,i) ((void)(sz), sprintf(s,f,i))
#endif
/*
@@ lua_strx2number converts a hexadecimal numeral to a number.
** In C99, 'strtod' does that conversion. Otherwise, you can
** leave 'lua_strx2number' undefined and Lua will provide its own
** implementation.
*/
# 594 "./lua/luaconf.h"
#if !defined(LUA_USE_C89)
#define lua_strx2number(s,p) lua_str2number(s,p)
#endif
/*
@@ lua_pointer2str converts a pointer to a readable string in a
** non-specified way.
*/
#define lua_pointer2str(buff,sz,p) l_sprintf(buff,sz,"%p",p)
/*
@@ lua_number2strx converts a float to a hexadecimal numeral.
** In C99, 'sprintf' (with format specifiers '%a'/'%A') does that.
** Otherwise, you can leave 'lua_number2strx' undefined and Lua will
** provide its own implementation.
*/
# 612 "./lua/luaconf.h"
#if !defined(LUA_USE_C89)
#define lua_number2strx(L,b,sz,f,n) \
((void)L, l_sprintf(b,sz,f,(LUAI_UACNUMBER)(n)))
#endif
/*
** 'strtof' and 'opf' variants for math functions are not valid in
** C89. Otherwise, the macro 'HUGE_VALF' is a good proxy for testing the
** availability of these variants. ('math.h' is already included in
** all files that use these macros.)
*/
# 624 "./lua/luaconf.h"
#if defined(LUA_USE_C89) || (defined(HUGE_VAL) && !defined(HUGE_VALF))
#undef l_mathop /* variants not available */
#undef l_mathop
#undef lua_str2number
#define l_mathop(op) (lua_Number)op /* no variant */
#define l_mathop(op) (lua_Number)op
#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
#endif
/*
@@ LUA_KCONTEXT is the type of the context ('ctx') for continuation
** functions. It must be a numerical type; Lua will use 'intptr_t' if
** available, otherwise it will use 'ptrdiff_t' (the nearest thing to
** 'intptr_t' in C89)
*/
# 638 "./lua/luaconf.h"
#define LUA_KCONTEXT ptrdiff_t
#if !defined(LUA_USE_C89) && defined(__STDC_VERSION__) && \
__STDC_VERSION__ >= 199901L
#include <stdint.h>
#if defined(INTPTR_MAX) /* even in C99 this type is optional */
#if defined(INTPTR_MAX)
#undef LUA_KCONTEXT
#define LUA_KCONTEXT intptr_t
#endif
#endif
/*
@@ lua_getlocaledecpoint gets the locale "radix character" (decimal point).
** Change that if you do not want to use C locales. (Code using this
** macro must include the header 'locale.h'.)
*/
#if !defined(lua_getlocaledecpoint)
#define lua_getlocaledecpoint() (localeconv()->decimal_point[0])
#endif
/*
** macros to improve jump prediction, used mostly for error handling
** and debug facilities. (Some macros in the Lua API use these macros.
** Define LUA_NOBUILTIN if you do not want '__builtin_expect' in your
** code.)
*/
# 666 "./lua/luaconf.h"
#if !defined(luai_likely)
#if defined(__GNUC__) && !defined(LUA_NOBUILTIN)
@ -677,59 +426,16 @@
#if defined(LUA_CORE) || defined(LUA_LIB)
/* shorter names for Lua's own use */
#define l_likely(x) luai_likely(x)
#define l_unlikely(x) luai_unlikely(x)
#endif
/* }================================================================== */
/*
** {==================================================================
** Language Variations
** =====================================================================
*/
/*
@@ LUA_NOCVTN2S/LUA_NOCVTS2N control how Lua performs some
** coercions. Define LUA_NOCVTN2S to turn off automatic coercion from
** numbers to strings. Define LUA_NOCVTS2N to turn off automatic
** coercion from strings to numbers.
*/
/* #define LUA_NOCVTN2S */
/* #define LUA_NOCVTS2N */
/*
@@ LUA_USE_APICHECK turns on several consistency checks on the C API.
** Define it as a help when debugging C code.
*/
# 710 "./lua/luaconf.h"
#if defined(LUA_USE_APICHECK)
#include <assert.h>
#define luai_apicheck(l,e) assert(e)
#endif
/* }================================================================== */
/*
** {==================================================================
** Macros that affect the API and must be stable (that is, must be the
** same when you compile Lua and when you compile code that links to
** Lua).
** =====================================================================
*/
/*
@@ LUAI_MAXSTACK limits the size of the Lua stack.
** CHANGE it if you need a different limit. This limit is arbitrary;
** its only purpose is to stop Lua from consuming unlimited stack
** space (and to reserve some numbers for pseudo-indices).
** (It must fit into max(size_t)/32.)
*/
# 733 "./lua/luaconf.h"
#if LUAI_IS32INT
#define LUAI_MAXSTACK 1000000
#else
@ -737,50 +443,32 @@
#endif
/*
@@ LUA_EXTRASPACE defines the size of a raw memory area associated with
** a Lua state with very fast access.
** CHANGE it if you need a different size.
*/
#define LUA_EXTRASPACE (sizeof(void *))
/*
@@ LUA_IDSIZE gives the maximum size for the description of the source
@@ of a function in debug information.
** CHANGE it if you want a different size.
*/
#define LUA_IDSIZE 60
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
*/
#define LUAL_BUFFERSIZE ((int)(16 * sizeof(void*) * sizeof(lua_Number)))
/*
@@ LUAI_MAXALIGN defines fields that, when used in a union, ensure
** maximum alignment for the other items in that union.
*/
#define LUAI_MAXALIGN lua_Number n; double u; void *s; lua_Integer i; long l
/* }================================================================== */
/* =================================================================== */
/*
** Local configuration. You can use this space to add your redefinitions
** without modifying the main part of the file.
*/
# 785 "./lua/luaconf.h"
#endif

View File

@ -1,8 +1,9 @@
/*
** $Id: lualib.h $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
# 1 "./lua/lualib.h"
#ifndef lualib_h
@ -11,7 +12,7 @@
#include "lua.h"
/* version suffix for environment variable names */
#define LUA_VERSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
@ -45,7 +46,7 @@ LUAMOD_API int (luaopen_debug) (lua_State *L);
LUAMOD_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
LUALIB_API void (luaL_openlibs) (lua_State *L);

View File

@ -1,8 +1,9 @@
/*
** $Id: lundump.h $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
# 1 "./lua/lundump.h"
#ifndef lundump_h
#define lundump_h
@ -12,24 +13,24 @@
#include "lzio.h"
/* data to catch conversion errors */
#define LUAC_DATA "\x19\x93\r\n\x1a\n"
#define LUAC_INT 0x5678
#define LUAC_NUM cast_num(370.5)
/*
** Encode major-minor version in one byte, one nibble for each
*/
#define MYINT(s) (s[0]-'0') /* assume one-digit numerals */
#define MYINT(s) (s[0]-'0')
#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
#define LUAC_FORMAT 0 /* this is the official format */
#define LUAC_FORMAT 0
/* load one chunk; from lundump.c */
LUAI_FUNC LClosure* luaU_undump (lua_State* L, ZIO* Z, const char* name);
/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
void* data, int strip);

View File

@ -1,8 +1,9 @@
/*
** $Id: lvm.h $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
# 1 "./lua/lvm.h"
#ifndef lvm_h
#define lvm_h
@ -16,55 +17,55 @@
#if !defined(LUA_NOCVTN2S)
#define cvt2str(o) ttisnumber(o)
#else
#define cvt2str(o) 0 /* no conversion from numbers to strings */
#define cvt2str(o) 0
#endif
#if !defined(LUA_NOCVTS2N)
#define cvt2num(o) ttisstring(o)
#else
#define cvt2num(o) 0 /* no conversion from strings to numbers */
#define cvt2num(o) 0
#endif
/*
** You can define LUA_FLOORN2I if you want to convert floats to integers
** by flooring them (instead of raising an error if they are not
** integral values)
*/
#if !defined(LUA_FLOORN2I)
#define LUA_FLOORN2I F2Ieq
#endif
/*
** Rounding modes for float->integer coercion
*/
typedef enum {
F2Ieq, /* no rounding; accepts only integral values */
F2Ifloor, /* takes the floor of the number */
F2Iceil /* takes the ceil of the number */
F2Ieq,
F2Ifloor,
F2Iceil
} F2Imod;
/* convert an object to a float (including string coercion) */
#define tonumber(o,n) \
(ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
/* convert an object to a float (without string coercion) */
#define tonumberns(o,n) \
(ttisfloat(o) ? ((n) = fltvalue(o), 1) : \
(ttisinteger(o) ? ((n) = cast_num(ivalue(o)), 1) : 0))
/* convert an object to an integer (including string coercion) */
#define tointeger(o,i) \
(l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \
: luaV_tointeger(o,i,LUA_FLOORN2I))
/* convert an object to an integer (without string coercion) */
#define tointegerns(o,i) \
(l_likely(ttisinteger(o)) ? (*(i) = ivalue(o), 1) \
: luaV_tointegerns(o,i,LUA_FLOORN2I))
@ -73,38 +74,30 @@ typedef enum {
#define intop(op,v1,v2) l_castU2S(l_castS2U(v1) op l_castS2U(v2))
#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
/*
** fast track for 'gettable': if 't' is a table and 't[k]' is present,
** return 1 with 'slot' pointing to 't[k]' (position of final result).
** Otherwise, return 0 (meaning it will have to check metamethod)
** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL
** (otherwise). 'f' is the raw get function to use.
*/
# 85 "./lua/lvm.h"
#define luaV_fastget(L,t,k,slot,f) \
(!ttistable(t) \
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
: (slot = f(hvalue(t), k), /* else, do raw access */ \
!isempty(slot))) /* result not empty? */
? (slot = NULL, 0) \
: (slot = f(hvalue(t), k), \
!isempty(slot)))
/*
** Special case of 'luaV_fastget' for integers, inlining the fast case
** of 'luaH_getint'.
*/
#define luaV_fastgeti(L,t,k,slot) \
(!ttistable(t) \
? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
? (slot = NULL, 0) \
: (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \
? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \
!isempty(slot))) /* result not empty? */
!isempty(slot)))
/*
** Finish a fast set operation (when fast get succeeds). In that case,
** 'slot' points to the place to put the value.
*/
#define luaV_finishfastset(L,t,slot,v) \
{ setobj2t(L, cast(TValue *,slot), v); \
luaC_barrierback(L, gcvalue(t), v); }

View File

@ -1,8 +1,9 @@
/*
** $Id: lzio.h $
** Buffered streams
** See Copyright Notice in lua.h
*/
# 1 "./lua/lzio.h"
#ifndef lzio_h
@ -13,7 +14,7 @@
#include "lmem.h"
#define EOZ (-1) /* end of stream */
#define EOZ (-1)
typedef struct Zio ZIO;
@ -46,18 +47,18 @@ typedef struct Mbuffer {
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
void *data);
LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */
LUAI_FUNC size_t luaZ_read (ZIO* z, void *b, size_t n);
/* --------- Private Part ------------------ */
struct Zio {
size_t n; /* bytes still unread */
const char *p; /* current position in buffer */
lua_Reader reader; /* reader function */
void *data; /* additional data */
lua_State *L; /* Lua state (for reader) */
size_t n;
const char *p;
lua_Reader reader;
void *data;
lua_State *L;
};

2152
include/sqlite3/sqlite3.h Normal file

File diff suppressed because it is too large Load Diff

BIN
lib/win/sqlite3.dll Normal file

Binary file not shown.

12
qml/Config.qml Normal file
View File

@ -0,0 +1,12 @@
import QtQuick 2.15
QtObject {
// Client configuration
// Player property of client
property string screenName: ""
property string password: ""
// Client data
property int roomCapacity: 0
}

View File

@ -1,4 +1,11 @@
var callbacks = {}
var callbacks = {};
callbacks["NetworkDelayTest"] = function(jsonData) {
Backend.notifyServer("Setup", JSON.stringify([
config.screenName,
config.password
]));
}
callbacks["ErrorMsg"] = function(jsonData) {
toast.show(jsonData);
@ -9,11 +16,14 @@ callbacks["EnterLobby"] = function(jsonData) {
// depth == 1 means the lobby page is not present in mainStack
if (mainStack.depth === 1) {
mainStack.push(lobby);
} else {
mainStack.pop();
}
mainWindow.busy = false;
}
callbacks["EnterRoom"] = function(jsonData) {
config.roomCapacity = JSON.parse(jsonData)[0];
mainStack.push(room);
mainWindow.busy = false;
}

View File

@ -14,11 +14,24 @@ Item {
text: "127.0.0.1"
}
TextField {
id: screenNameEdit
text: "player"
}
/*TextField {
id: avatarEdit
text: "liubei"
}*/
TextField {
id: passwordEdit
text: ""
echoMode: TextInput.Password
passwordCharacter: "*"
}
Button {
text: "Join Server"
onClicked: {
config.screenName = screenNameEdit.text;
config.password = passwordEdit.text;
mainWindow.busy = true;
toast.show("Connecting to host...");
Backend.joinServer(server_addr.text);
@ -27,6 +40,8 @@ Item {
Button {
text: "Console start"
onClicked: {
config.screenName = screenNameEdit.text;
config.password = passwordEdit.text;
mainWindow.busy = true;
toast.show("Connecting to host...");
Backend.startServer(9527);

View File

@ -43,7 +43,7 @@ Item {
onClicked: {
mainWindow.busy = true;
Backend.notifyServer(
"enter_room",
"EnterRoom",
JSON.stringify([roomId])
);
}

View File

@ -20,7 +20,6 @@ Item {
text: "quit"
anchors.bottom: parent.bottom
onClicked: {
mainStack.pop();
Backend.notifyServer("QuitRoom", "[]");
}
}
@ -32,7 +31,7 @@ Item {
TextField {
id: lua
Layout.fillWidth: true
text: "player"
text: "print \"Hello world.\""
}
Button {
text: "DoLuaScript"
@ -62,7 +61,19 @@ Item {
id: photos
model: photoModel
Photo {
// TODO
general: modelData.general
screenName: modelData.screenName
role: modelData.role
kingdom: modelData.kingdom
netstate: modelData.netstate
maxHp: modelData.maxHp
hp: modelData.hp
seatNumber: modelData.seatNumber
isDead: modelData.isDead
dying: modelData.dying
faceturned: modelData.faceturned
chained: modelData.chained
drank: modelData.drank
}
}
@ -88,10 +99,63 @@ Item {
id: dashboard
width: roomScene.width
anchors.top: roomArea.bottom
self.general: dashboardModel.general
self.screenName: dashboardModel.screenName
self.role: dashboardModel.role
self.kingdom: dashboardModel.kingdom
self.netstate: dashboardModel.netstate
self.maxHp: dashboardModel.maxHp
self.hp: dashboardModel.hp
self.seatNumber: dashboardModel.seatNumber
self.isDead: dashboardModel.isDead
self.dying: dashboardModel.dying
self.faceturned: dashboardModel.faceturned
self.chained: dashboardModel.chained
self.drank: dashboardModel.drank
}
Component.onCompleted: {
toast.show("Sucesessfully entered room.");
dashboardModel = {
general: config.avatar,
screenName: config.screenName,
role: "unknown",
kingdom: "qun",
netstate: "online",
maxHp: 0,
hp: 0,
seatNumber: 1,
isDead: false,
dying: false,
faceturned: false,
chained: false,
drank: false
}
playerNum = config.roomCapacity;
let i;
for (i = 1; i < playerNum; i++) {
photoModel.push({
general: "",
screenName: "",
role: "unknown",
kingdom: "qun",
netstate: "online",
maxHp: 0,
hp: 0,
seatNumber: i + 1,
isDead: false,
dying: false,
faceturned: false,
chained: false,
drank: false
});
}
photoModel = photoModel; // Force the Repeater reload
Logic.arrangePhotos();
}
}

View File

@ -8,15 +8,15 @@ Item {
width: 175
height: 233
scale: 0.8
property string general: "liubei"
property string general: ""
property string screenName: ""
property string role: "lord"
property string kingdom: "shu"
property string netstate: "trust"
property string role: "unknown"
property string kingdom: "qun"
property string netstate: "online"
property int handcards: 0
property int maxHp: 4
property int hp: 3
property int seatNumber: 3
property int maxHp: 0
property int hp: 0
property int seatNumber: 1
property bool isDead: false
property bool dying: false
property bool faceturned: false
@ -41,7 +41,7 @@ Item {
color: "white"
width: 24
wrapMode: Text.WordWrap
text: "刘备"
text: ""
}
HpBar {
@ -60,7 +60,7 @@ Item {
smooth: true
visible: false
fillMode: Image.PreserveAspectCrop
source: SkinBank.GENERAL_DIR + general
source: (general != "") ? SkinBank.GENERAL_DIR + general : ""
}
Rectangle {

View File

@ -47,3 +47,59 @@ function arrangePhotos() {
item.y = region.y;
}
}
callbacks["AddPlayer"] = function(jsonData) {
// jsonData: string screenName, string avatar
for (let i = 0; i < photoModel.length; i++) {
if (photoModel[i].screenName === "") {
let data = JSON.parse(jsonData);
let name = data[0];
let avatar = data[1];
photoModel[i] = {
general: avatar,
screenName: name,
role: "unknown",
kingdom: "qun",
netstate: "online",
maxHp: 0,
hp: 0,
seatNumber: i + 1,
isDead: false,
dying: false,
faceturned: false,
chained: false,
drank: false
};
photoModel = photoModel;
arrangePhotos();
return;
}
}
}
callbacks["RemovePlayer"] = function(jsonData) {
// jsonData: string screenName
let name = JSON.parse(jsonData)[0];
for (let i = 0; i < photoModel.length; i++) {
if (photoModel[i].screenName === name) {
photoModel[i] = {
general: "",
screenName: "",
role: "unknown",
kingdom: "qun",
netstate: "online",
maxHp: 0,
hp: 0,
seatNumber: i + 1,
isDead: false,
dying: false,
faceturned: false,
chained: false,
drank: false
};
photoModel = photoModel;
arrangePhotos();
return;
}
}
}

View File

@ -45,6 +45,10 @@ Window {
visible: mainWindow.busy === true
}
Config {
id: config
}
Rectangle {
id: toast
opacity: 0

12
server/init.sql Normal file
View File

@ -0,0 +1,12 @@
CREATE TABLE userinfo (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(255),
password CHAR(64),
avatar VARCHAR(64),
lastLoginIp VARCHAR(64),
banned BOOLEAN
);
CREATE TABLE banip (
ip VARCHAR(64)
);

View File

@ -32,16 +32,18 @@ set(freekill_HEADERS
if (WIN32)
set(LUA_LIB ${PROJECT_SOURCE_DIR}/lib/win/lua54.dll)
set(SQLITE3_LIB ${PROJECT_SOURCE_DIR}/lib/win/sqlite3.dll)
else ()
set(LUA_LIB lua5.4)
set(SQLITE3_LIB sqlite3)
endif ()
source_group("Include" FILES ${freekill_HEADERS})
add_executable(FreeKill ${freekill_SRCS})
target_link_libraries(FreeKill ${LUA_LIB} Qt5::Qml Qt5::Gui Qt5::Network Qt5::Multimedia)
target_link_libraries(FreeKill ${LUA_LIB} ${SQLITE3_LIB} Qt5::Qml Qt5::Gui Qt5::Network Qt5::Multimedia)
add_custom_command(
OUTPUT ${PROJECT_SOURCE_DIR}/src/swig/freekill-wrap.cxx
DEPENDS ${PROJECT_SOURCE_DIR}/src/swig/freekill.i
DEPENDS ${PROJECT_SOURCE_DIR}/src/swig/*.i
COMMENT "Generating freekill-wrap.cxx"
COMMAND swig -c++ -lua -Wall -o
${PROJECT_SOURCE_DIR}/src/swig/freekill-wrap.cxx

View File

@ -23,6 +23,7 @@ Client::Client(QObject* parent)
Client::~Client()
{
ClientInstance = nullptr;
lua_close(L);
router->getSocket()->disconnectFromHost();
router->getSocket()->deleteLater();
}

View File

@ -1,5 +1,6 @@
#include "global.h"
#include <QtCore>
#include <QFileDevice>
extern "C" {
int luaopen_freekill(lua_State *);
@ -25,3 +26,66 @@ bool DoLuaScript(lua_State *L, const char *script)
return true;
}
sqlite3 *OpenDatabase(const QString &filename)
{
sqlite3 *ret;
int rc;
if (!QFile::exists(filename)) {
QFile file("./server/init.sql");
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "cannot open init.sql. Quit now.";
qApp->exit(1);
}
QTextStream in(&file);
char *err_msg;
sqlite3_open(filename.toLatin1().data(), &ret);
rc = sqlite3_exec(ret, in.readAll().toLatin1().data(), nullptr, nullptr, &err_msg);
if (rc != SQLITE_OK ) {
qDebug() << "sqlite error:" << err_msg;
sqlite3_free(err_msg);
sqlite3_close(ret);
qApp->exit(1);
}
} else {
rc = sqlite3_open(filename.toLatin1().data(), &ret);
if (rc != SQLITE_OK) {
qDebug() << "Cannot open database:" << sqlite3_errmsg(ret);
sqlite3_close(ret);
qApp->exit(1);
}
}
return ret;
}
// callback for handling SELECT expression
static int callback(void *jsonDoc, int argc, char **argv, char **cols) {
QJsonObject obj;
for (int i = 0; i < argc; i++) {
QJsonArray arr = obj[QString(cols[i])].toArray();
arr << QString(argv[i] ? argv[i] : "#null");
obj[QString(cols[i])] = arr;
}
((QJsonObject *)jsonDoc)->swap(obj);
return 0;
}
QJsonObject SelectFromDatabase(sqlite3 *db, const QString &sql) {
QJsonObject obj;
sqlite3_exec(db, sql.toUtf8().data(), callback, (void *)&obj, nullptr);
return obj;
}
QString SelectFromDb(sqlite3 *db, const QString &sql) {
QJsonObject obj = SelectFromDatabase(db, sql);
return QJsonDocument(obj).toJson();
}
void ExecSQL(sqlite3 *db, const QString &sql) {
sqlite3_exec(db, sql.toUtf8().data(), nullptr, nullptr, nullptr);
}
void CloseDatabase(sqlite3 *db) {
sqlite3_close(db);
}

View File

@ -2,6 +2,8 @@
#define _GLOBAL_H
#include <lua.hpp>
#include <sqlite3.h>
#include <QtCore>
// utilities
typedef int LuaFunction;
@ -9,4 +11,11 @@ typedef int LuaFunction;
lua_State *CreateLuaState();
bool DoLuaScript(lua_State *L, const char *script);
sqlite3 *OpenDatabase(const QString &filename = "./server/users.db");
QJsonObject SelectFromDatabase(sqlite3 *db, const QString &sql);
// For Lua
QString SelectFromDb(sqlite3 *db, const QString &sql);
void ExecSQL(sqlite3 *db, const QString &sql);
void CloseDatabase(sqlite3 *db);
#endif // _GLOBAL_H

View File

@ -44,7 +44,7 @@ signals:
private:
uint id;
QString screenName;
QString screenName; // screenName should not be same.
QString avatar;
State state;
bool ready;

View File

@ -11,6 +11,8 @@ ClientSocket::ClientSocket(QTcpSocket* socket)
{
socket->setParent(this);
this->socket = socket;
timerSignup.setSingleShot(true);
connect(&timerSignup, &QTimer::timeout, this, &ClientSocket::disconnectFromHost);
init();
}

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QAbstractSocket>
#include <QHostAddress>
#include <QTimer>
class QTcpSocket;
@ -21,6 +22,7 @@ public:
bool isConnected() const;
QString peerName() const;
QString peerAddress() const;
QTimer timerSignup;
signals:
void message_got(const QByteArray& msg);

View File

@ -18,6 +18,9 @@ void ServerSocket::processNewConnection()
{
QTcpSocket *socket = server->nextPendingConnection();
ClientSocket *connection = new ClientSocket(socket);
connect(connection, &ClientSocket::disconnected, this, [connection](){
connection->deleteLater();
});
emit new_connection(connection);
}

View File

@ -1,6 +1,8 @@
#include "room.h"
#include "serverplayer.h"
#include "server.h"
#include <QJsonArray>
#include <QJsonDocument>
Room::Room(Server* server)
{
@ -17,6 +19,7 @@ Room::Room(Server* server)
Room::~Room()
{
// TODO
disconnect();
}
Server *Room::getServer() const
@ -77,14 +80,33 @@ void Room::setOwner(ServerPlayer *owner)
void Room::addPlayer(ServerPlayer *player)
{
if (!player) return;
QJsonArray jsonData;
// First, notify other players the new player is entering
if (!isLobby()) {
jsonData << player->getScreenName();
jsonData << player->getAvatar();
doBroadcastNotify(getPlayers(), "AddPlayer", QJsonDocument(jsonData).toJson());
}
players.append(player);
player->setRoom(this);
if (isLobby()) {
player->doNotify("EnterLobby", "[]");
} else {
player->doNotify("EnterRoom", "[]");
// Second, let the player enter room and add other players
jsonData = QJsonArray();
jsonData << (int)this->capacity;
player->doNotify("EnterRoom", QJsonDocument(jsonData).toJson());
foreach (ServerPlayer *p, getOtherPlayers(player)) {
jsonData = QJsonArray();
jsonData << p->getScreenName();
jsonData << p->getAvatar();
player->doNotify("AddPlayer", QJsonDocument(jsonData).toJson());
}
}
qDebug() << "Player #" << player->getUid() << " entered room";
emit playerAdded(player);
}
@ -95,6 +117,11 @@ void Room::removePlayer(ServerPlayer *player)
if (isLobby()) return;
// player->doNotify("QuitRoom", "[]");
QJsonArray jsonData;
jsonData << player->getScreenName();
doBroadcastNotify(getPlayers(), "RemovePlayer", QJsonDocument(jsonData).toJson());
if (isAbandoned()) {
emit abandoned();
} else if (player == owner) {
@ -108,6 +135,13 @@ QList<ServerPlayer *> Room::getPlayers() const
return players;
}
QList<ServerPlayer *> Room::getOtherPlayers(ServerPlayer* expect) const
{
QList<ServerPlayer *> others = getPlayers();
others.removeOne(expect);
return others;
}
ServerPlayer *Room::findPlayer(uint id) const
{
foreach (ServerPlayer *p, players) {

View File

@ -31,6 +31,7 @@ public:
void addPlayer(ServerPlayer *player);
void removePlayer(ServerPlayer *player);
QList<ServerPlayer*> getPlayers() const;
QList<ServerPlayer *> getOtherPlayers(ServerPlayer *expect) const;
ServerPlayer *findPlayer(uint id) const;
void setGameLogic(GameLogic *logic);

View File

@ -7,6 +7,8 @@
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QRegExp>
#include <QCryptographicHash>
Server *ServerInstance;
@ -26,11 +28,16 @@ Server::Server(QObject* parent)
L = CreateLuaState();
DoLuaScript(L, "lua/freekill.lua");
DoLuaScript(L, "lua/server/server.lua");
db = OpenDatabase();
}
Server::~Server()
{
ServerInstance = nullptr;
m_lobby->deleteLater();
lua_close(L);
sqlite3_close(db);
}
bool Server::listen(const QHostAddress& address, ushort port)
@ -50,9 +57,6 @@ void Server::createRoom(ServerPlayer* owner, const QString &name, uint capacity)
m_lobby = room;
else
rooms.insert(room->getId(), room);
#ifdef QT_DEBUG
qDebug() << "Room #" << room->getId() << " created.";
#endif
}
Room *Server::findRoom(uint id) const
@ -91,16 +95,117 @@ void Server::updateRoomList()
void Server::processNewConnection(ClientSocket* client)
{
qDebug() << client->peerAddress() << "connected";
// version check, file check, ban IP, reconnect, etc
connect(client, &ClientSocket::disconnected, this, [client](){
qDebug() << client->peerAddress() << "disconnected";
});
// network delay test
QJsonArray body;
body << -2;
body << (Router::TYPE_NOTIFICATION | Router::SRC_SERVER | Router::DEST_CLIENT);
body << "NetworkDelayTest";
body << "[]";
client->send(QJsonDocument(body).toJson(QJsonDocument::Compact));
// Note: the client should send a setup string next
connect(client, &ClientSocket::message_got, this, &Server::processRequest);
client->timerSignup.start(30000);
}
void Server::processRequest(const QByteArray& msg)
{
ClientSocket *client = qobject_cast<ClientSocket *>(sender());
client->disconnect(this, SLOT(processRequest(const QByteArray &)));
client->timerSignup.stop();
bool valid = true;
QJsonDocument doc = QJsonDocument::fromJson(msg);
if (doc.isNull() || !doc.isArray()) {
valid = false;
} else {
if (doc.array().size() != 4
|| doc[0] != -2
|| doc[1] != (Router::TYPE_NOTIFICATION | Router::SRC_CLIENT | Router::DEST_SERVER)
|| doc[2] != "Setup"
)
valid = false;
else
valid = (QJsonDocument::fromJson(doc[3].toString().toUtf8()).array().size() == 2);
}
if (!valid) {
qDebug() << "Invalid setup string:" << msg;
QJsonArray body;
body << -2;
body << (Router::TYPE_NOTIFICATION | Router::SRC_SERVER | Router::DEST_CLIENT);
body << "ErrorMsg";
body << "INVALID SETUP STRING";
client->send(QJsonDocument(body).toJson(QJsonDocument::Compact));
client->disconnectFromHost();
return;
}
QJsonArray arr = QJsonDocument::fromJson(doc[3].toString().toUtf8()).array();
handleNameAndPassword(client, arr[0].toString(), arr[1].toString());
}
void Server::handleNameAndPassword(ClientSocket *client, const QString& name, const QString& password)
{
// First check the name and password
// Matches a string that does not contain special characters
QRegExp nameExp("[^\\0000-\\0057\\0072-\\0100\\0133-\\0140\\0173-\\0177]+");
QByteArray passwordHash = QCryptographicHash::hash(password.toLatin1(), QCryptographicHash::Sha256).toHex();
bool passed = false;
QJsonObject result;
if (nameExp.exactMatch(name)) {
// Then we check the database,
QString sql_find = QString("SELECT * FROM userinfo \
WHERE name='%1';").arg(name);
result = SelectFromDatabase(db, sql_find);
QJsonArray arr = result["password"].toArray();
if (arr.isEmpty()) {
// not present in database, register
QString sql_reg = QString("INSERT INTO userinfo (name,password,\
avatar,lastLoginIp,banned) VALUES ('%1','%2','%3','%4',%5);")
.arg(name)
.arg(QString(passwordHash))
.arg("liubei")
.arg(client->peerAddress())
.arg("FALSE");
ExecSQL(db, sql_reg);
result = SelectFromDatabase(db, sql_find); // refresh result
passed = true;
} else {
// check if password is the same
passed = (passwordHash == arr[0].toString());
}
}
if (passed) {
ServerPlayer *player = new ServerPlayer(lobby());
player->setSocket(client);
players.insert(player->getUid(), player);
#ifdef QT_DEBUG
qDebug() << "ServerPlayer #" << player->getUid() << "connected.";
qDebug() << "His address is " << client->peerAddress();
#endif
client->disconnect(this);
connect(client, &ClientSocket::disconnected, this, [player](){
qDebug() << "Player" << player->getUid() << "disconnected";
});
player->setScreenName(name);
player->setAvatar(result["avatar"].toArray()[0].toString());
player->setId(result["id"].toArray()[0].toInt());
players.insert(player->getId(), player);
lobby()->addPlayer(player);
} else {
qDebug() << client->peerAddress() << "entered wrong password";
QJsonArray body;
body << -2;
body << (Router::TYPE_NOTIFICATION | Router::SRC_SERVER | Router::DEST_CLIENT);
body << "ErrorMsg";
body << "username or password error";
client->send(QJsonDocument(body).toJson(QJsonDocument::Compact));
client->disconnectFromHost();
return;
}
}
void Server::onRoomAbandoned()

View File

@ -6,6 +6,7 @@
#include <QMap>
#include <QHostAddress>
#include <lua.hpp>
#include <sqlite3.h>
class ServerSocket;
class ClientSocket;
@ -41,6 +42,7 @@ signals:
public slots:
void processNewConnection(ClientSocket *client);
void processRequest(const QByteArray &msg);
void onRoomAbandoned();
void onUserDisconnected();
@ -53,6 +55,9 @@ private:
QHash<uint, ServerPlayer *> players;
lua_State *L;
sqlite3 *db;
void handleNameAndPassword(ClientSocket *client, const QString &name, const QString &password);
};
extern Server *ServerInstance;

40
src/swig/client.i Normal file
View File

@ -0,0 +1,40 @@
%nodefaultctor QmlBackend;
%nodefaultdtor QmlBackend;
class QmlBackend : public QObject {
public:
void emitNotifyUI(const char *command, const char *json_data);
};
extern QmlBackend *Backend;
%nodefaultctor Client;
%nodefaultdtor Client;
class Client : public QObject {
public:
void requestServer(const QString &command,
const QString &json_data, int timeout = -1);
void replyToServer(const QString &command, const QString &json_data);
void notifyServer(const QString &command, const QString &json_data);
LuaFunction callback;
};
extern Client *ClientInstance;
%{
void Client::callLua(const QString& command, const QString& json_data)
{
Q_ASSERT(callback);
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
SWIG_NewPointerObj(L, this, SWIGTYPE_p_Client, 0);
lua_pushstring(L, command.toUtf8());
lua_pushstring(L, json_data.toUtf8());
int error = lua_pcall(L, 3, 0, 0);
if (error) {
const char *error_msg = lua_tostring(L, -1);
qDebug() << error_msg;
}
}
%}

View File

@ -9,225 +9,9 @@
#include "qmlbackend.h"
%}
// ------------------------------------------------------
// type bindings
// ------------------------------------------------------
// LuaFunction(int) and lua function
%naturalvar LuaFunction;
%typemap(in) LuaFunction
%{
if (lua_isfunction(L, $input)) {
lua_pushvalue(L, $input);
$1 = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
$1 = 0;
}
%}
%typemap(out) LuaFunction
%{
lua_rawgeti(L, LUA_REGISTRYINDEX, $1);
SWIG_arg ++;
%}
// QString and lua string
%naturalvar QString;
%typemap(in, checkfn = "lua_isstring") QString
%{ $1 = lua_tostring(L, $input); %}
%typemap(out) QString
%{ lua_pushstring(L, $1.toUtf8()); SWIG_arg++; %}
// const QString &
%typemap(arginit) QString const &
"QString $1_str;"
%typemap(in, checkfn = "lua_isstring") QString const &
%{
$1_str = QString::fromUtf8(lua_tostring(L, $input));
$1 = &$1_str;
%}
%typemap(out) QString const &
%{ lua_pushstring(L, $1.toUtf8()); SWIG_arg++; %}
// ------------------------------------------------------
// classes and functions
// ------------------------------------------------------
class QObject {
public:
QString objectName();
void setObjectName(const char *name);
bool inherits(const char *class_name);
bool setProperty(const char *name, const QVariant &value);
QVariant property(const char *name) const;
void setParent(QObject *parent);
void deleteLater();
};
class QThread {};
class QmlBackend : public QObject {
public:
void emitNotifyUI(const char *command, const char *json_data);
};
extern QmlBackend *Backend;
class Client : public QObject {
public:
void requestServer(const QString &command,
const QString &json_data, int timeout = -1);
void replyToServer(const QString &command, const QString &json_data);
void notifyServer(const QString &command, const QString &json_data);
LuaFunction callback;
};
extern Client *ClientInstance;
%{
void Client::callLua(const QString& command, const QString& json_data)
{
Q_ASSERT(callback);
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
SWIG_NewPointerObj(L, this, SWIGTYPE_p_Client, 0);
lua_pushstring(L, command.toUtf8());
lua_pushstring(L, json_data.toUtf8());
int error = lua_pcall(L, 3, 0, 0);
if (error) {
const char *error_msg = lua_tostring(L, -1);
qDebug() << error_msg;
}
}
%}
class Server : public QObject {
public:
void createRoom(ServerPlayer *owner, const QString &name, unsigned int capacity);
Room *findRoom(unsigned int id) const;
Room *lobby() const;
ServerPlayer *findPlayer(unsigned int id) const;
void updateRoomList();
LuaFunction callback;
};
%{
void Server::callLua(const QString& command, const QString& json_data)
{
Q_ASSERT(callback);
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
SWIG_NewPointerObj(L, this, SWIGTYPE_p_Server, 0);
lua_pushstring(L, command.toUtf8());
lua_pushstring(L, json_data.toUtf8());
int error = lua_pcall(L, 3, 0, 0);
if (error) {
const char *error_msg = lua_tostring(L, -1);
qDebug() << error_msg;
}
}
%}
extern Server *ServerInstance;
class Player : public QObject {
enum State{
Invalid,
Online,
Trust,
Offline
};
unsigned int getId() const;
void setId(unsigned int id);
QString getScreenName() const;
void setScreenName(const QString &name);
QString getAvatar() const;
void setAvatar(const QString &avatar);
State getState() const;
QString getStateString() const;
void setState(State state);
void setStateString(const QString &state);
bool isReady() const;
void setReady(bool ready);
};
class ClientPlayer : public Player {
public:
ClientPlayer(unsigned int id, QObject *parent = nullptr);
~ClientPlayer();
};
extern ClientPlayer *Self;
class ServerPlayer : public Player {
public:
explicit ServerPlayer(Room *room);
~ServerPlayer();
unsigned int getUid() const;
void setSocket(ClientSocket *socket);
Server *getServer() const;
Room *getRoom() const;
void setRoom(Room *room);
void speak(const QString &message);
void doRequest(const QString &command,
const QString &json_data, int timeout = -1);
void doReply(const QString &command, const QString &json_data);
void doNotify(const QString &command, const QString &json_data);
void prepareForRequest(const QString &command,
const QVariant &data = QVariant());
};
class Room : public QThread {
public:
explicit Room(Server *m_server);
~Room();
// Property reader & setter
// ==================================={
Server *getServer() const;
unsigned int getId() const;
bool isLobby() const;
QString getName() const;
void setName(const QString &name);
unsigned int getCapacity() const;
void setCapacity(unsigned int capacity);
bool isFull() const;
bool isAbandoned() const;
ServerPlayer *getOwner() const;
void setOwner(ServerPlayer *owner);
void addPlayer(ServerPlayer *player);
void removePlayer(ServerPlayer *player);
QList<ServerPlayer *> getPlayers() const;
ServerPlayer *findPlayer(unsigned int id) const;
void setGameLogic(GameLogic *logic);
GameLogic *getGameLogic() const;
// ====================================}
void startGame();
void doRequest(const QList<ServerPlayer *> targets, int timeout);
void doNotify(const QList<ServerPlayer *> targets, int timeout);
};
%include "naturalvar.i"
%include "qt.i"
%include "player.i"
%include "client.i"
%include "server.i"
%include "sqlite3.i"

44
src/swig/naturalvar.i Normal file
View File

@ -0,0 +1,44 @@
// ------------------------------------------------------
// type bindings
// ------------------------------------------------------
// LuaFunction(int) and lua function
%naturalvar LuaFunction;
%typemap(in) LuaFunction
%{
if (lua_isfunction(L, $input)) {
lua_pushvalue(L, $input);
$1 = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
$1 = 0;
}
%}
%typemap(out) LuaFunction
%{
lua_rawgeti(L, LUA_REGISTRYINDEX, $1);
SWIG_arg ++;
%}
// QString and lua string
%naturalvar QString;
%typemap(in, checkfn = "lua_isstring") QString
%{ $1 = lua_tostring(L, $input); %}
%typemap(out) QString
%{ lua_pushstring(L, $1.toUtf8()); SWIG_arg++; %}
// const QString &
%typemap(arginit) QString const &
"QString $1_str;"
%typemap(in, checkfn = "lua_isstring") QString const &
%{
$1_str = QString::fromUtf8(lua_tostring(L, $input));
$1 = &$1_str;
%}
%typemap(out) QString const &
%{ lua_pushstring(L, $1.toUtf8()); SWIG_arg++; %}

59
src/swig/player.i Normal file
View File

@ -0,0 +1,59 @@
%nodefaultctor Player;
%nodefaultdtor Player;
class Player : public QObject {
public:
enum State{
Invalid,
Online,
Trust,
Offline
};
unsigned int getId() const;
void setId(unsigned int id);
QString getScreenName() const;
void setScreenName(const QString &name);
QString getAvatar() const;
void setAvatar(const QString &avatar);
State getState() const;
QString getStateString() const;
void setState(State state);
void setStateString(const QString &state);
bool isReady() const;
void setReady(bool ready);
};
%nodefaultctor ClientPlayer;
%nodefaultdtor ClientPlayer;
class ClientPlayer : public Player {
public:
};
extern ClientPlayer *Self;
%nodefaultctor ServerPlayer;
%nodefaultdtor ServerPlayer;
class ServerPlayer : public Player {
public:
unsigned int getUid() const;
void setSocket(ClientSocket *socket);
Server *getServer() const;
Room *getRoom() const;
void setRoom(Room *room);
void speak(const QString &message);
void doRequest(const QString &command,
const QString &json_data, int timeout = -1);
void doReply(const QString &command, const QString &json_data);
void doNotify(const QString &command, const QString &json_data);
void prepareForRequest(const QString &command,
const QVariant &data = QVariant());
};

12
src/swig/qt.i Normal file
View File

@ -0,0 +1,12 @@
class QObject {
public:
QString objectName();
void setObjectName(const char *name);
bool inherits(const char *class_name);
bool setProperty(const char *name, const QVariant &value);
QVariant property(const char *name) const;
void setParent(QObject *parent);
void deleteLater();
};
class QThread {};

68
src/swig/server.i Normal file
View File

@ -0,0 +1,68 @@
%nodefaultctor Server;
%nodefaultdtor Server;
class Server : public QObject {
public:
void createRoom(ServerPlayer *owner, const QString &name, unsigned int capacity);
Room *findRoom(unsigned int id) const;
Room *lobby() const;
ServerPlayer *findPlayer(unsigned int id) const;
void updateRoomList();
LuaFunction callback;
};
%{
void Server::callLua(const QString& command, const QString& json_data)
{
Q_ASSERT(callback);
lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
SWIG_NewPointerObj(L, this, SWIGTYPE_p_Server, 0);
lua_pushstring(L, command.toUtf8());
lua_pushstring(L, json_data.toUtf8());
int error = lua_pcall(L, 3, 0, 0);
if (error) {
const char *error_msg = lua_tostring(L, -1);
qDebug() << error_msg;
}
}
%}
extern Server *ServerInstance;
%nodefaultctor Room;
%nodefaultdtor Room;
class Room : public QThread {
public:
// Property reader & setter
// ==================================={
Server *getServer() const;
unsigned int getId() const;
bool isLobby() const;
QString getName() const;
void setName(const QString &name);
unsigned int getCapacity() const;
void setCapacity(unsigned int capacity);
bool isFull() const;
bool isAbandoned() const;
ServerPlayer *getOwner() const;
void setOwner(ServerPlayer *owner);
void addPlayer(ServerPlayer *player);
void removePlayer(ServerPlayer *player);
QList<ServerPlayer *> getPlayers() const;
ServerPlayer *findPlayer(unsigned int id) const;
void setGameLogic(GameLogic *logic);
GameLogic *getGameLogic() const;
// ====================================}
void startGame();
void doRequest(const QList<ServerPlayer *> targets, int timeout);
void doNotify(const QList<ServerPlayer *> targets, int timeout);
};

6
src/swig/sqlite3.i Normal file
View File

@ -0,0 +1,6 @@
struct sqlite3;
sqlite3 *OpenDatabase(const QString &filename);
QString SelectFromDb(sqlite3 *db, const QString &sql);
void ExecSQL(sqlite3 *db, const QString &sql);
void CloseDatabase(sqlite3 *db);

View File

@ -25,6 +25,7 @@ void QmlBackend::startServer(ushort port)
void QmlBackend::joinServer(QString address)
{
if (ClientInstance != nullptr) return;
class Client *client = new class Client(this);
connect(client, &Client::error_message, [this, client](const QString &msg){
client->deleteLater();