diff --git a/engine/lua/ldo.cpp b/engine/lua/ldo.cpp index e4f5b8b3524..859d5c4143c 100644 --- a/engine/lua/ldo.cpp +++ b/engine/lua/ldo.cpp @@ -205,7 +205,7 @@ void luaD_precall(TObject *f, StkId base, int32 nResults) { L->ci->tf = NULL; L->ci->pc = NULL; } else { - Byte *pc = tfvalue(f)->code; + byte *pc = tfvalue(f)->code; if (lua_callhook) luaD_callHook(base, tfvalue(f), 0); luaD_checkstack((*pc++) + EXTRA_STACK); diff --git a/engine/lua/llex.h b/engine/lua/llex.h index 309fe440307..0c7d9632708 100644 --- a/engine/lua/llex.h +++ b/engine/lua/llex.h @@ -7,8 +7,8 @@ #ifndef llex_h #define llex_h -#include "lobject.h" -#include "lzio.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lzio.h" #define FIRST_RESERVED 260 diff --git a/engine/lua/lmathlib.cpp b/engine/lua/lmathlib.cpp index 18e2f54742a..14d791a255a 100644 --- a/engine/lua/lmathlib.cpp +++ b/engine/lua/lmathlib.cpp @@ -5,168 +5,147 @@ */ -#include "lauxlib.h" -#include "lua.h" -#include "lualib.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lua.h" +#include "engine/lua/lualib.h" #ifndef LOCAL_PI #define LOCAL_PI (3.14159265358979323846) #endif - #define FROMRAD(a) ((a)*(180.0/LOCAL_PI)) #define TORAD(a) ((a)*(LOCAL_PI/180.0)) - -static void math_abs (void) -{ - double d = luaL_check_number(1); - if (d < 0) d = -d; - lua_pushnumber(d); +static void math_abs() { + double d = luaL_check_number(1); + if (d < 0) + d = -d; + lua_pushnumber(d); } -static void math_sin (void) -{ - lua_pushnumber(sin(TORAD(luaL_check_number(1)))); +static void math_sin() { + lua_pushnumber(sin(TORAD(luaL_check_number(1)))); } -static void math_cos (void) -{ - lua_pushnumber(cos(TORAD(luaL_check_number(1)))); +static void math_cos() { + lua_pushnumber(cos(TORAD(luaL_check_number(1)))); } -static void math_tan (void) -{ - lua_pushnumber(tan(TORAD(luaL_check_number(1)))); +static void math_tan() { + lua_pushnumber(tan(TORAD(luaL_check_number(1)))); } -static void math_asin (void) -{ - lua_pushnumber(FROMRAD(asin(luaL_check_number(1)))); +static void math_asin() { + lua_pushnumber(FROMRAD(asin(luaL_check_number(1)))); } -static void math_acos (void) -{ - lua_pushnumber(FROMRAD(acos(luaL_check_number(1)))); +static void math_acos() { + lua_pushnumber(FROMRAD(acos(luaL_check_number(1)))); } -static void math_atan (void) -{ - lua_pushnumber(FROMRAD(atan(luaL_check_number(1)))); +static void math_atan() { + lua_pushnumber(FROMRAD(atan(luaL_check_number(1)))); } -static void math_ceil (void) -{ - lua_pushnumber(ceil(luaL_check_number(1))); +static void math_ceil() { + lua_pushnumber(ceil(luaL_check_number(1))); } -static void math_floor (void) -{ - lua_pushnumber(floor(luaL_check_number(1))); +static void math_floor() { + lua_pushnumber(floor(luaL_check_number(1))); } -static void math_mod (void) -{ - lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2))); +static void math_mod() { + lua_pushnumber(fmod(luaL_check_number(1), luaL_check_number(2))); } -static void math_sqrt (void) -{ - lua_pushnumber(sqrt(luaL_check_number(1))); +static void math_sqrt() { + lua_pushnumber(sqrt(luaL_check_number(1))); } -static void math_pow (void) -{ - lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2))); +static void math_pow() { + lua_pushnumber(pow(luaL_check_number(1), luaL_check_number(2))); } -static void math_deg (void) -{ - lua_pushnumber(luaL_check_number(1)*(180.0/LOCAL_PI)); -} - -static void math_rad (void) -{ - lua_pushnumber(luaL_check_number(1)*(LOCAL_PI/180.0)); -} - -static void math_min (void) -{ - int32 i = 1; - double dmin = luaL_check_number(i); - while (lua_getparam(++i) != LUA_NOOBJECT) { - double d = luaL_check_number(i); - if (d < dmin) - dmin = d; - } - lua_pushnumber(dmin); +static void math_deg() { + lua_pushnumber(luaL_check_number(1) * (180.0/LOCAL_PI)); } -static void math_max (void) -{ - int32 i = 1; - double dmax = luaL_check_number(i); - while (lua_getparam(++i) != LUA_NOOBJECT) { - double d = luaL_check_number(i); - if (d > dmax) - dmax = d; - } - lua_pushnumber(dmax); +static void math_rad() { + lua_pushnumber(luaL_check_number(1) * (LOCAL_PI / 180.0)); } -static void math_random (void) -{ - /* the '%' is needed because on some systems (SunOS!) "rand()" may */ - /* return a value bigger than RAND_MAX... */ - double r = (double)(rand()%RAND_MAX) / (double)RAND_MAX; - double l = luaL_opt_number(1, 0); - if (l == 0) - lua_pushnumber(r); - else - lua_pushnumber((int32)(r*l)+1); +static void math_min() { + int32 i = 1; + double dmin = luaL_check_number(i); + while (lua_getparam(++i) != LUA_NOOBJECT) { + double d = luaL_check_number(i); + if (d < dmin) + dmin = d; + } + lua_pushnumber(dmin); } -static void math_randomseed (void) -{ - srand((unsigned int)luaL_check_number(1)); +static void math_max() { + int32 i = 1; + double dmax = luaL_check_number(i); + while (lua_getparam(++i) != LUA_NOOBJECT) { + double d = luaL_check_number(i); + if (d > dmax) + dmax = d; + } + lua_pushnumber(dmax); } +static void math_random() { + double r = (double)(rand() % RAND_MAX) / (double)RAND_MAX; + double l = luaL_opt_number(1, 0); + if (l == 0) + lua_pushnumber(r); + else + lua_pushnumber((int32)(r * l) + 1); +} + +static void math_randomseed() { + srand((unsigned int)luaL_check_number(1)); +} static struct luaL_reg mathlib[] = { -{"abs", math_abs}, -{"sin", math_sin}, -{"cos", math_cos}, -{"tan", math_tan}, -{"asin", math_asin}, -{"acos", math_acos}, -{"atan", math_atan}, -{"ceil", math_ceil}, -{"floor", math_floor}, -{"mod", math_mod}, -{"sqrt", math_sqrt}, -{"min", math_min}, -{"max", math_max}, -{"deg", math_deg}, -{"rad", math_rad}, -{"random", math_random}, -{"randomseed", math_randomseed} + { "abs", math_abs}, + { "sin", math_sin}, + { "cos", math_cos}, + { "tan", math_tan}, + { "asin", math_asin}, + { "acos", math_acos}, + { "atan", math_atan}, + { "ceil", math_ceil}, + { "floor", math_floor}, + { "mod", math_mod}, + { "sqrt", math_sqrt}, + { "min", math_min}, + { "max", math_max}, + { "deg", math_deg}, + { "rad", math_rad}, + { "random", math_random}, + { "randomseed", math_randomseed} }; static luaL_reg powFunc[] = { -{"math_pow", math_pow} + { "math_pow", math_pow } }; /* ** Open math library */ -void lua_mathlibopen (void) -{ - luaL_openlib(mathlib, (sizeof(mathlib)/sizeof(mathlib[0]))); - luaL_addlibtolist(powFunc, (sizeof(powFunc)/sizeof(powFunc[0]))); - lua_pushstring("deg"); lua_setglobal("_TRIGMODE"); - lua_pushcfunction(math_pow); - lua_pushnumber(0); /* to get its tag */ - lua_settagmethod(lua_tag(lua_pop()), "pow"); - lua_pushnumber(LOCAL_PI); lua_setglobal("PI"); +void lua_mathlibopen() { + luaL_openlib(mathlib, (sizeof(mathlib) / sizeof(mathlib[0]))); + luaL_addlibtolist(powFunc, (sizeof(powFunc) / sizeof(powFunc[0]))); + lua_pushstring("deg"); + lua_setglobal("_TRIGMODE"); + lua_pushcfunction(math_pow); + lua_pushnumber(0); // to get its tag + lua_settagmethod(lua_tag(lua_pop()), "pow"); + lua_pushnumber(LOCAL_PI); + lua_setglobal("PI"); } diff --git a/engine/lua/lmem.cpp b/engine/lua/lmem.cpp index 7f5c61787a0..32cb465ca49 100644 --- a/engine/lua/lmem.cpp +++ b/engine/lua/lmem.cpp @@ -5,28 +5,21 @@ */ +#include "engine/lua/lmem.h" +#include "engine/lua/lstate.h" +#include "engine/lua/lua.h" -#include "lmem.h" -#include "lstate.h" -#include "lua.h" - - - -int32 luaM_growaux (void **block, int32 nelems, int32 size, - const char *errormsg, int32 limit) -{ - if (nelems >= limit) - lua_error(errormsg); - nelems = (nelems == 0) ? 32 : nelems*2; - if (nelems > limit) - nelems = limit; - *block = luaM_realloc(*block, nelems*size); - return (int32)nelems; +int32 luaM_growaux(void **block, int32 nelems, int32 size, const char *errormsg, int32 limit) { + if (nelems >= limit) + lua_error(errormsg); + nelems = (nelems == 0) ? 32 : nelems * 2; + if (nelems > limit) + nelems = limit; + *block = luaM_realloc(*block, nelems * size); + return (int32)nelems; } - - -#ifndef DEBUG +#ifndef LUA_DEBUG /* ** generic allocation routine. @@ -34,76 +27,62 @@ int32 luaM_growaux (void **block, int32 nelems, int32 size, ** since realloc(NULL, s)==malloc(s) and realloc(b, 0)==free(b). ** But some systems (e.g. Sun OS) are not that ANSI... */ -void *luaM_realloc (void *block, int32 size) -{ - if (size == 0) { - if (block) { - free(block); - } - return NULL; - } - block = block ? realloc(block, size) : malloc(size); - if (block == NULL) - lua_error(memEM); - return block; +void *luaM_realloc(void *block, int32 size) { + if (size == 0) { + if (block) { + free(block); + } + return NULL; + } + block = block ? realloc(block, size) : malloc(size); + if (!block) + lua_error(memEM); + return block; } - - #else -/* DEBUG */ - -#include - +/* LUA_DEBUG */ #define HEADER (sizeof(double)) - #define MARK 55 int32 numblocks = 0; int32 totalmem = 0; - -static void *checkblock (void *block) -{ - int32 *b = (uint32 *)((char *)block - HEADER); - int32 size = *b; - LUA_ASSERT(*(((char *)b)+size+HEADER) == MARK, - "corrupted block"); - numblocks--; - totalmem -= size; - return b; +static void *checkblock(void *block) { + int32 *b = (uint32 *)((char *)block - HEADER); + int32 size = *b; + LUA_ASSERT(*(((char *)b) + size + HEADER) == MARK, "corrupted block"); + numblocks--; + totalmem -= size; + return b; } - -void *luaM_realloc (void *block, int32 size) -{ - int32 realsize = HEADER+size+1; - if (realsize != (size_t)realsize) - lua_error("Allocation Error: Block too big"); - if (size == 0) { /* ANSI dosen't need this, but some machines... */ - if (block) { - int32 *b = (int32 *)((char *)block - HEADER); - memset(block, -1, *b); /* erase block */ - block = checkblock(block); - free(block); - } - return NULL; - } - if (block) { - block = checkblock(block); - block = (int32 *)realloc(block, realsize); - } - else - block = (int32 *)malloc(realsize); - if (block == NULL) - lua_error(memEM); - totalmem += size; - numblocks++; - *(int32 *)block = size; - *(((char *)block)+size+HEADER) = MARK; - return (int32 *)((char *)block+HEADER); +void *luaM_realloc(void *block, int32 size) { + int32 realsize = HEADER + size + 1; + if (realsize != (size_t)realsize) + lua_error("Allocation Error: Block too big"); + if (size == 0) { // ANSI dosen't need this, but some machines... + if (block) { + int32 *b = (int32 *)((char *)block - HEADER); + memset(block, -1, *b); // erase block + block = checkblock(block); + free(block); + } + return NULL; + } + if (block) { + block = checkblock(block); + block = (int32 *)realloc(block, realsize); + } else + block = (int32 *)malloc(realsize); + if (!block) + lua_error(memEM); + totalmem += size; + numblocks++; + *(int32 *)block = size; + *(((char *)block) + size + HEADER) = MARK; + return (int32 *)((char *)block + HEADER); } - #endif diff --git a/engine/lua/lmem.h b/engine/lua/lmem.h index 0cb988ab071..19b7dccbbbb 100644 --- a/engine/lua/lmem.h +++ b/engine/lua/lmem.h @@ -9,33 +9,24 @@ #include "common/sys.h" - -#ifndef NULL -#define NULL 0 -#endif - - -/* memory error messages */ -#define codeEM "code size overflow" -#define constantEM "constant table overflow" -#define refEM "reference table overflow" -#define tableEM "table overflow" -#define memEM "not enough memory" +// memory error messages +#define codeEM "code size overflow" +#define constantEM "constant table overflow" +#define refEM "reference table overflow" +#define tableEM "table overflow" +#define memEM "not enough memory" void *luaM_realloc (void *oldblock, int32 size); -int32 luaM_growaux (void **block, int32 nelems, int32 size, - const char *errormsg, int32 limit); +int32 luaM_growaux (void **block, int32 nelems, int32 size, const char *errormsg, int32 limit); -#define luaM_free(b) free((b)) -#define luaM_malloc(t) malloc((t)) -#define luaM_new(t) ((t *)malloc(sizeof(t))) -#define luaM_newvector(n,t) ((t *)malloc((n)*sizeof(t))) -#define luaM_growvector(old,n,t,e,l) \ - (luaM_growaux((void**)old,n,sizeof(t),e,l)) -#define luaM_reallocvector(v,n,t) ((t *)realloc(v,(n)*sizeof(t))) +#define luaM_free(b) free((b)) +#define luaM_malloc(t) malloc((t)) +#define luaM_new(t) ((t *)malloc(sizeof(t))) +#define luaM_newvector(n, t) ((t *)malloc((n) * sizeof(t))) +#define luaM_growvector(old, n, t, e, l) (luaM_growaux((void**)old, n, sizeof(t), e, l)) +#define luaM_reallocvector(v, n, t) ((t *)realloc(v,(n) * sizeof(t))) - -#ifdef DEBUG +#ifdef LUA_DEBUG extern int32 numblocks; extern int32 totalmem; #endif diff --git a/engine/lua/lobject.cpp b/engine/lua/lobject.cpp index 9a4a0475f42..8ae49fcdcc8 100644 --- a/engine/lua/lobject.cpp +++ b/engine/lua/lobject.cpp @@ -4,61 +4,63 @@ ** See Copyright Notice in lua.h */ -#include "lobject.h" -#include "lua.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lua.h" - -const char *luaO_typenames[] = { /* ORDER LUA_T */ - "userdata", "number", "string", "table", "function", "function", "task", - "nil", "function", "mark", "mark", "mark", "line", NULL +const char *luaO_typenames[] = { // ORDER LUA_T + "userdata", "number", "string", "table", "function", "function", "task", + "nil", "function", "mark", "mark", "mark", "line", NULL }; - -TObject luaO_nilobject = {LUA_T_NIL, {NULL}}; +TObject luaO_nilobject = { LUA_T_NIL, { NULL } }; +// hash dimensions values +static int32 dimensions[] = { + 5, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421, + 12853, 25717, 51437, 102811, 205619, 411233, 822433, + 1644817, 3289613, 6579211, 13158023, MAX_INT +}; -/* hash dimensions values */ -static int32 dimensions[] = - {5, 11, 23, 47, 97, 197, 397, 797, 1597, 3203, 6421, - 12853, 25717, 51437, 102811, 205619, 411233, 822433, - 1644817, 3289613, 6579211, 13158023, MAX_INT}; - - -int32 luaO_redimension (int32 oldsize) -{ - int32 i; - for (i=0; dimensions[i] oldsize) - return dimensions[i]; - } - lua_error("table overflow"); - return 0; /* to avoid warnings */ +int32 luaO_redimension(int32 oldsize) { + int32 i; + for (i = 0; dimensions[i] < MAX_INT; i++) { + if (dimensions[i] > oldsize) + return dimensions[i]; + } + lua_error("table overflow"); + return 0; // to avoid warnings } - -int32 luaO_equalObj (TObject *t1, TObject *t2) -{ - if (ttype(t1) != ttype(t2)) return 0; - switch (ttype(t1)) { - case LUA_T_NIL: return 1; - case LUA_T_NUMBER: return nvalue(t1) == nvalue(t2); - case LUA_T_STRING: case LUA_T_USERDATA: return svalue(t1) == svalue(t2); - case LUA_T_ARRAY: return avalue(t1) == avalue(t2); - case LUA_T_PROTO: return tfvalue(t1) == tfvalue(t2); - case LUA_T_CPROTO: return fvalue(t1) == fvalue(t2); - case LUA_T_CLOSURE: return t1->value.cl == t2->value.cl; - case LUA_T_TASK: return nvalue(t1) == nvalue(t2); - default: - LUA_INTERNALERROR("invalid type"); - return 0; /* UNREACHABLE */ - } +int32 luaO_equalObj(TObject *t1, TObject *t2) { + if (ttype(t1) != ttype(t2)) + return 0; + switch (ttype(t1)) { + case LUA_T_NIL: + return 1; + case LUA_T_NUMBER: return + nvalue(t1) == nvalue(t2); + case LUA_T_STRING: + case LUA_T_USERDATA: + return svalue(t1) == svalue(t2); + case LUA_T_ARRAY: + return avalue(t1) == avalue(t2); + case LUA_T_PROTO: + return tfvalue(t1) == tfvalue(t2); + case LUA_T_CPROTO: + return fvalue(t1) == fvalue(t2); + case LUA_T_CLOSURE: + return t1->value.cl == t2->value.cl; + case LUA_T_TASK: + return nvalue(t1) == nvalue(t2); + default: + LUA_INTERNALERROR("invalid type"); + return 0; // UNREACHABLE + } } - -void luaO_insertlist (GCnode *root, GCnode *node) -{ - node->next = root->next; - root->next = node; - node->marked = 0; +void luaO_insertlist(GCnode *root, GCnode *node) { + node->next = root->next; + root->next = node; + node->marked = 0; } diff --git a/engine/lua/lobject.h b/engine/lua/lobject.h index b1fd2395eb7..098cf461cfd 100644 --- a/engine/lua/lobject.h +++ b/engine/lua/lobject.h @@ -7,21 +7,17 @@ #ifndef lobject_h #define lobject_h +#include "engine/lua/lua.h" -#include "lua.h" - - -#ifdef DEBUG -#include "lauxlib.h" -#define LUA_INTERNALERROR(s) \ - luaL_verror("INTERNAL ERROR - %s [%s:%d]",(s),__FILE__,__LINE__) -#define LUA_ASSERT(c,s) { if (!(c)) LUA_INTERNALERROR(s); } +#ifdef LUA_DEBUG +#include "engine/lua/lauxlib.h" +#define LUA_INTERNALERROR(s) luaL_verror("INTERNAL ERROR - %s [%s:%d]", (s), __FILE__, __LINE__) +#define LUA_ASSERT(c, s) { if (!(c)) LUA_INTERNALERROR(s); } #else -#define LUA_INTERNALERROR(s) /* empty */ -#define LUA_ASSERT(c,s) /* empty */ +#define LUA_INTERNALERROR(s) // empty +#define LUA_ASSERT(c, s) // empty #endif - /* ** "real" is the type "number" of Lua ** GREP LUA_NUMBER to change that @@ -37,14 +33,8 @@ typedef LUA_NUM_TYPE real; -#define Byte lua_Byte /* some systems have Byte as a predefined type */ -typedef byte Byte; /* unsigned 8 bits */ - - -#define MAX_INT (2147483647-2) /* maximum value of an int (-2 for safety) */ -#define MAX_WORD 65534 - -typedef unsigned long IntPoint; /* unsigned with same size as a pointer (for hashing) */ +#define MAX_INT (2147483647 - 2) // maximum value of an int (-2 for safety) +#define MAX_WORD 65534 /* @@ -53,99 +43,87 @@ typedef unsigned long IntPoint; /* unsigned with same size as a pointer (for has ** grep "ORDER LUA_T" */ typedef enum { - LUA_T_USERDATA = 0, /* tag default for userdata */ - LUA_T_NUMBER = -1, /* fixed tag for numbers */ - LUA_T_STRING = -2, /* fixed tag for strings */ - LUA_T_ARRAY = -3, /* tag default for tables (or arrays) */ - LUA_T_PROTO = -4, /* fixed tag for functions */ - LUA_T_CPROTO = -5, /* fixed tag for Cfunctions */ - LUA_T_TASK = -6, /* task tag */ - LUA_T_NIL = -7, /* last "pre-defined" tag */ - LUA_T_CLOSURE = -8, - LUA_T_CLMARK = -9, /* mark for closures */ - LUA_T_PMARK = -10, /* mark for Lua prototypes */ - LUA_T_CMARK = -11, /* mark for C prototypes */ - LUA_T_LINE = -12 + LUA_T_USERDATA = 0, // tag default for userdata + LUA_T_NUMBER = -1, // fixed tag for numbers + LUA_T_STRING = -2, // fixed tag for strings + LUA_T_ARRAY = -3, // tag default for tables (or arrays) + LUA_T_PROTO = -4, // fixed tag for functions + LUA_T_CPROTO = -5, // fixed tag for Cfunctions + LUA_T_TASK = -6, // task tag + LUA_T_NIL = -7, // last "pre-defined" tag + LUA_T_CLOSURE = -8, + LUA_T_CLMARK = -9, // mark for closures + LUA_T_PMARK = -10, // mark for Lua prototypes + LUA_T_CMARK = -11, // mark for C prototypes + LUA_T_LINE = -12 } lua_Type; #define NUM_TYPES 12 #define NUM_TAGS 8 - typedef union { - lua_CFunction f; /* LUA_T_CPROTO, LUA_T_CMARK */ - real n; /* LUA_T_NUMBER */ - struct TaggedString *ts; /* LUA_T_STRING, LUA_T_USERDATA */ - struct TProtoFunc *tf; /* LUA_T_PROTO, LUA_T_PMARK */ - struct Closure *cl; /* LUA_T_CLOSURE, LUA_T_CLMARK */ - struct Hash *a; /* LUA_T_ARRAY */ - int32 i; /* LUA_T_LINE */ + lua_CFunction f; // LUA_T_CPROTO, LUA_T_CMARK + real n; // LUA_T_NUMBER + struct TaggedString *ts; // LUA_T_STRING, LUA_T_USERDATA + struct TProtoFunc *tf; // LUA_T_PROTO, LUA_T_PMARK + struct Closure *cl; // LUA_T_CLOSURE, LUA_T_CLMARK + struct Hash *a; // LUA_T_ARRAY + int32 i; // LUA_T_LINE } Value; - typedef struct TObject { - lua_Type ttype; - Value value; + lua_Type ttype; + Value value; } TObject; - - /* ** generic header for garbage collector lists */ typedef struct GCnode { - struct GCnode *next; - int32 marked; + struct GCnode *next; + int32 marked; } GCnode; - /* ** String headers for string table */ typedef struct TaggedString { - GCnode head; - unsigned long hash; - int32 constindex; /* hint to reuse constants (= -1 if this is a userdata) */ - union { - struct { - TObject globalval; - int32 len; /* if this is a string, here is its length */ - } s; - struct { - int32 tag; - void *v; /* if this is a userdata, here is its value */ - } d; - } u; - char str[1]; /* \0 byte already reserved */ + GCnode head; + unsigned long hash; + int32 constindex; // hint to reuse constants (= -1 if this is a userdata) + union { + struct { + TObject globalval; + int32 len; // if this is a string, here is its length + } s; + struct { + int32 tag; + void *v; // if this is a userdata, here is its value + } d; + } u; + char str[1]; // \0 byte already reserved } TaggedString; - - - /* ** Function Prototypes */ typedef struct TProtoFunc { - GCnode head; - struct TObject *consts; - int32 nconsts; - Byte *code; /* ends with opcode ENDCODE */ - int32 lineDefined; - TaggedString *fileName; - struct LocVar *locvars; /* ends with line = -1 */ + GCnode head; + struct TObject *consts; + int32 nconsts; + byte *code; // ends with opcode ENDCODE + int32 lineDefined; + TaggedString *fileName; + struct LocVar *locvars; // ends with line = -1 } TProtoFunc; typedef struct LocVar { - TaggedString *varname; /* NULL signals end of scope */ - int32 line; + TaggedString *varname; // NULL signals end of scope + int32 line; } LocVar; - - - - -/* Macros to access structure members */ +// Macros to access structure members #define ttype(o) ((o)->ttype) #define nvalue(o) ((o)->value.n) #define svalue(o) ((o)->value.ts->str) @@ -153,8 +131,7 @@ typedef struct LocVar { #define clvalue(o) ((o)->value.cl) #define avalue(o) ((o)->value.a) #define fvalue(o) ((o)->value.f) -#define tfvalue(o) ((o)->value.tf) - +#define tfvalue(o) ((o)->value.tf) #define protovalue(o) ((o)->value.cl->consts) @@ -162,36 +139,32 @@ typedef struct LocVar { ** Closures */ typedef struct Closure { - GCnode head; - int32 nelems; /* not included the first one (always the prototype) */ - TObject consts[1]; /* at least one for prototype */ + GCnode head; + int32 nelems; // not included the first one (always the prototype) + TObject consts[1]; // at least one for prototype } Closure; - - typedef struct node { - TObject ref; - TObject val; + TObject ref; + TObject val; } Node; typedef struct Hash { - GCnode head; - Node *node; - int32 nhash; - int32 nuse; - int32 htag; + GCnode head; + Node *node; + int32 nhash; + int32 nuse; + int32 htag; } Hash; - extern const char *luaO_typenames[]; - extern TObject luaO_nilobject; -int32 luaO_equalObj (TObject *t1, TObject *t2); -int32 luaO_redimension (int32 oldsize); -void luaO_insertlist (GCnode *root, GCnode *node); +int32 luaO_equalObj(TObject *t1, TObject *t2); +int32 luaO_redimension(int32 oldsize); +void luaO_insertlist(GCnode *root, GCnode *node); -#define luaO_memup(d,s,n) memmove(d,s,n) -#define luaO_memdown(d,s,n) memmove(d,s,n) +#define luaO_memup(d, s, n) memmove(d, s, n) +#define luaO_memdown(d, s, n) memmove(d, s, n) #endif diff --git a/engine/lua/lopcodes.h b/engine/lua/lopcodes.h index 4468fa7fb48..7115376acef 100644 --- a/engine/lua/lopcodes.h +++ b/engine/lua/lopcodes.h @@ -7,176 +7,171 @@ #ifndef lopcodes_h #define lopcodes_h - /* ** NOTICE: variants of the same opcode must be consecutive: First, those ** with byte parameter, then with built-in parameters, and last with ** word parameter. */ - typedef enum { -/* name parm before after side effect ------------------------------------------------------------------------------*/ -ENDCODE,/* - - - */ +// name parm before after side effect +//----------------------------------------------------------------------------- + ENDCODE, // - - - -PUSHNIL,/* b - nil_0...nil_b */ -PUSHNIL0,/* - - nil */ + PUSHNIL, // b - nil_0...nil_b + PUSHNIL0, // - - nil -PUSHNUMBER,/* b - (float)b */ -PUSHNUMBER0,/* - - 0.0 */ -PUSHNUMBER1,/* - - 1.0 */ -PUSHNUMBER2,/* - - 2.0 */ -PUSHNUMBERW,/* w - (float)w */ + PUSHNUMBER, // b - (float)b + PUSHNUMBER0, // - - 0.0 + PUSHNUMBER1, // - - 1.0 + PUSHNUMBER2, // - - 2.0 + PUSHNUMBERW, // w - (float)w -PUSHCONSTANT,/* b - CNST[b] */ -PUSHCONSTANT0,/*- - CNST[0] */ -PUSHCONSTANT1,/*- - CNST[1] */ -PUSHCONSTANT2,/*- - CNST[2] */ -PUSHCONSTANT3,/*- - CNST[3] */ -PUSHCONSTANT4,/*- - CNST[4] */ -PUSHCONSTANT5,/*- - CNST[5] */ -PUSHCONSTANT6,/*- - CNST[6] */ -PUSHCONSTANT7,/*- - CNST[7] */ -PUSHCONSTANTW,/*w - CNST[w] */ + PUSHCONSTANT, // b - CNST[b] + PUSHCONSTANT0, // - - CNST[0] + PUSHCONSTANT1, // - - CNST[1] + PUSHCONSTANT2, // - - CNST[2] + PUSHCONSTANT3, // - - CNST[3] + PUSHCONSTANT4, // - - CNST[4] + PUSHCONSTANT5, // - - CNST[5] + PUSHCONSTANT6, // - - CNST[6] + PUSHCONSTANT7, // - - CNST[7] + PUSHCONSTANTW, // w - CNST[w] -PUSHUPVALUE,/* b - Closure[b] */ -PUSHUPVALUE0,/* - - Closure[0] */ -PUSHUPVALUE1,/* - - Closure[1] */ + PUSHUPVALUE, // b - Closure[b] + PUSHUPVALUE0, // - - Closure[0] + PUSHUPVALUE1, // - - Closure[1] -PUSHLOCAL,/* b - LOC[b] */ -PUSHLOCAL0,/* - - LOC[0] */ -PUSHLOCAL1,/* - - LOC[1] */ -PUSHLOCAL2,/* - - LOC[2] */ -PUSHLOCAL3,/* - - LOC[3] */ -PUSHLOCAL4,/* - - LOC[4] */ -PUSHLOCAL5,/* - - LOC[5] */ -PUSHLOCAL6,/* - - LOC[6] */ -PUSHLOCAL7,/* - - LOC[7] */ + PUSHLOCAL, // b - LOC[b] + PUSHLOCAL0, // - - LOC[0] + PUSHLOCAL1, // - - LOC[1] + PUSHLOCAL2, // - - LOC[2] + PUSHLOCAL3, // - - LOC[3] + PUSHLOCAL4, // - - LOC[4] + PUSHLOCAL5, // - - LOC[5] + PUSHLOCAL6, // - - LOC[6] + PUSHLOCAL7, // - - LOC[7] -GETGLOBAL,/* b - VAR[CNST[b]] */ -GETGLOBAL0,/* - - VAR[CNST[0]] */ -GETGLOBAL1,/* - - VAR[CNST[1]] */ -GETGLOBAL2,/* - - VAR[CNST[2]] */ -GETGLOBAL3,/* - - VAR[CNST[3]] */ -GETGLOBAL4,/* - - VAR[CNST[4]] */ -GETGLOBAL5,/* - - VAR[CNST[5]] */ -GETGLOBAL6,/* - - VAR[CNST[6]] */ -GETGLOBAL7,/* - - VAR[CNST[7]] */ -GETGLOBALW,/* w - VAR[CNST[w]] */ + GETGLOBAL, // b - VAR[CNST[b]] + GETGLOBAL0, // - - VAR[CNST[0]] + GETGLOBAL1, // - - VAR[CNST[1]] + GETGLOBAL2, // - - VAR[CNST[2]] + GETGLOBAL3, // - - VAR[CNST[3]] + GETGLOBAL4, // - - VAR[CNST[4]] + GETGLOBAL5, // - - VAR[CNST[5]] + GETGLOBAL6, // - - VAR[CNST[6]] + GETGLOBAL7, // - - VAR[CNST[7]] + GETGLOBALW, // w - VAR[CNST[w]] -GETTABLE,/* - i t t[i] */ + GETTABLE, // - i t t[i] -GETDOTTED,/* b t t[CNST[b]] */ -GETDOTTED0,/* - t t[CNST[0]] */ -GETDOTTED1,/* - t t[CNST[1]] */ -GETDOTTED2,/* - t t[CNST[2]] */ -GETDOTTED3,/* - t t[CNST[3]] */ -GETDOTTED4,/* - t t[CNST[4]] */ -GETDOTTED5,/* - t t[CNST[5]] */ -GETDOTTED6,/* - t t[CNST[6]] */ -GETDOTTED7,/* - t t[CNST[7]] */ -GETDOTTEDW,/* w t t[CNST[w]] */ + GETDOTTED, // b t t[CNST[b]] + GETDOTTED0, // - t t[CNST[0]] + GETDOTTED1, // - t t[CNST[1]] + GETDOTTED2, // - t t[CNST[2]] + GETDOTTED3, // - t t[CNST[3]] + GETDOTTED4, // - t t[CNST[4]] + GETDOTTED5, // - t t[CNST[5]] + GETDOTTED6, // - t t[CNST[6]] + GETDOTTED7, // - t t[CNST[7]] + GETDOTTEDW, // w t t[CNST[w]] -PUSHSELF,/* b t t t[CNST[b]] */ -PUSHSELF0,/* - t t t[CNST[0]] */ -PUSHSELF1,/* - t t t[CNST[1]] */ -PUSHSELF2,/* - t t t[CNST[2]] */ -PUSHSELF3,/* - t t t[CNST[3]] */ -PUSHSELF4,/* - t t t[CNST[4]] */ -PUSHSELF5,/* - t t t[CNST[5]] */ -PUSHSELF6,/* - t t t[CNST[6]] */ -PUSHSELF7,/* - t t t[CNST[7]] */ -PUSHSELFW,/* w t t t[CNST[w]] */ + PUSHSELF, // b t t t[CNST[b]] + PUSHSELF0, // - t t t[CNST[0]] + PUSHSELF1, // - t t t[CNST[1]] + PUSHSELF2, // - t t t[CNST[2]] + PUSHSELF3, // - t t t[CNST[3]] + PUSHSELF4, // - t t t[CNST[4]] + PUSHSELF5, // - t t t[CNST[5]] + PUSHSELF6, // - t t t[CNST[6]] + PUSHSELF7, // - t t t[CNST[7]] + PUSHSELFW, // w t t t[CNST[w]] -CREATEARRAY,/* b - newarray(size = b) */ -CREATEARRAY0,/* - - newarray(size = 0) */ -CREATEARRAY1,/* - - newarray(size = 1) */ -CREATEARRAYW,/* w - newarray(size = w) */ + CREATEARRAY, // b - newarray(size = b) + CREATEARRAY0, // - - newarray(size = 0) + CREATEARRAY1, // - - newarray(size = 1) + CREATEARRAYW, // w - newarray(size = w) -SETLOCAL,/* b x - LOC[b]=x */ -SETLOCAL0,/* - x - LOC[0]=x */ -SETLOCAL1,/* - x - LOC[1]=x */ -SETLOCAL2,/* - x - LOC[2]=x */ -SETLOCAL3,/* - x - LOC[3]=x */ -SETLOCAL4,/* - x - LOC[4]=x */ -SETLOCAL5,/* - x - LOC[5]=x */ -SETLOCAL6,/* - x - LOC[6]=x */ -SETLOCAL7,/* - x - LOC[7]=x */ + SETLOCAL, // b x - LOC[b]=x + SETLOCAL0, // - x - LOC[0]=x + SETLOCAL1, // - x - LOC[1]=x + SETLOCAL2, // - x - LOC[2]=x + SETLOCAL3, // - x - LOC[3]=x + SETLOCAL4, // - x - LOC[4]=x + SETLOCAL5, // - x - LOC[5]=x + SETLOCAL6, // - x - LOC[6]=x + SETLOCAL7, // - x - LOC[7]=x -SETGLOBAL,/* b x - VAR[CNST[b]]=x */ -SETGLOBAL0,/* - x - VAR[CNST[0]]=x */ -SETGLOBAL1,/* - x - VAR[CNST[1]]=x */ -SETGLOBAL2,/* - x - VAR[CNST[2]]=x */ -SETGLOBAL3,/* - x - VAR[CNST[3]]=x */ -SETGLOBAL4,/* - x - VAR[CNST[4]]=x */ -SETGLOBAL5,/* - x - VAR[CNST[5]]=x */ -SETGLOBAL6,/* - x - VAR[CNST[6]]=x */ -SETGLOBAL7,/* - x - VAR[CNST[7]]=x */ -SETGLOBALW,/* w x - VAR[CNST[w]]=x */ + SETGLOBAL, // b x - VAR[CNST[b]]=x + SETGLOBAL0, // - x - VAR[CNST[0]]=x + SETGLOBAL1, // - x - VAR[CNST[1]]=x + SETGLOBAL2, // - x - VAR[CNST[2]]=x + SETGLOBAL3, // - x - VAR[CNST[3]]=x + SETGLOBAL4, // - x - VAR[CNST[4]]=x + SETGLOBAL5, // - x - VAR[CNST[5]]=x + SETGLOBAL6, // - x - VAR[CNST[6]]=x + SETGLOBAL7, // - x - VAR[CNST[7]]=x + SETGLOBALW, // w x - VAR[CNST[w]]=x -SETTABLE0,/* - v i t - t[i]=v */ + SETTABLE0, // - vci t - t[i]=v -SETTABLE,/* b v a_b...a_1 i t a_b...a_1 i t t[i]=v */ + SETTABLE, // b v a_b...a_1 i t a_b...a_1 i t t[i]=v -SETLIST,/* b c v_c...v_1 t - t[i+b*FPF]=v_i */ -SETLIST0,/* b v_b...v_1 t - t[i]=v_i */ -SETLISTW,/* w c v_c...v_1 t - t[i+w*FPF]=v_i */ + SETLIST, // b c v_c...v_1 t - t[i+b*FPF]=v_i + SETLIST0, // b v_b...v_1 t - t[i]=v_i + SETLISTW, // w c v_c...v_1 t - t[i+w*FPF]=v_i -SETMAP,/* b v_b k_b ...v_0 k_0 t t t[k_i]=v_i */ -SETMAP0,/* - v_0 k_0 t t t[k_0]=v_0 */ + SETMAP, // b v_b k_b ...v_0 k_0 t t t[k_i]=v_i + SETMAP0, // - v_0 k_0 t t t[k_0]=v_0 -EQOP,/* - y x (x==y)? 1 : nil */ -NEQOP,/* - y x (x~=y)? 1 : nil */ -LTOP,/* - y x (xy)? 1 : nil */ -GEOP,/* - y x (x>=y)? 1 : nil */ -ADDOP,/* - y x x+y */ -SUBOP,/* - y x x-y */ -MULTOP,/* - y x x*y */ -DIVOP,/* - y x x/y */ -POWOP,/* - y x x^y */ -CONCOP,/* - y x x..y */ -MINUSOP,/* - x -x */ -NOTOP,/* - x (x==nil)? 1 : nil */ + EQOP, // - y x (x==y)? 1 : nil + NEQOP, // - y x (x~=y)? 1 : nil + LTOP, // - y x (xy)? 1 : nil + GEOP, // - y x (x>=y)? 1 : nil + ADDOP, // - y x x+y + SUBOP, // - y x x-y + MULTOP, // - y x x*y + DIVOP, // - y x x/y + POWOP, // - y x x^y + CONCOP, // - y x x..y + MINUSOP, // - x -x + NOTOP, // - x (x==nil)? 1 : nil -ONTJMP,/* b x (x!=nil)? x : - (x!=nil)? PC+=b */ -ONTJMPW,/* w x (x!=nil)? x : - (x!=nil)? PC+=w */ -ONFJMP,/* b x (x==nil)? x : - (x==nil)? PC+=b */ -ONFJMPW,/* w x (x==nil)? x : - (x==nil)? PC+=w */ -JMP,/* b - - PC+=b */ -JMPW,/* w - - PC+=w */ -IFFJMP,/* b x - (x==nil)? PC+=b */ -IFFJMPW,/* w x - (x==nil)? PC+=w */ -IFTUPJMP,/* b x - (x!=nil)? PC-=b */ -IFTUPJMPW,/* w x - (x!=nil)? PC-=w */ -IFFUPJMP,/* b x - (x==nil)? PC-=b */ -IFFUPJMPW,/* w x - (x==nil)? PC-=w */ + ONTJMP, // b x (x!=nil)? x : - (x!=nil)? PC+=b + ONTJMPW, // w x (x!=nil)? x : - (x!=nil)? PC+=w + ONFJMP, // b x (x==nil)? x : - (x==nil)? PC+=b + ONFJMPW, // w x (x==nil)? x : - (x==nil)? PC+=w + JMP, // b - - PC+=b + JMPW, // w - - PC+=w + IFFJMP, // b x - (x==nil)? PC+=b + IFFJMPW, // w x - (x==nil)? PC+=w + IFTUPJMP, // b x - (x!=nil)? PC-=b + IFTUPJMPW, // w x - (x!=nil)? PC-=w + IFFUPJMP, // b x - (x==nil)? PC-=b + IFFUPJMPW, // w x - (x==nil)? PC-=w -CLOSURE,/* c f v_c...v_1 closure(f, v_c...v_1) */ -CLOSURE0,/* - f closure(f) */ -CLOSURE1,/* - f v closure(f, v) */ + CLOSURE, // c f v_c...v_1 closure(f, v_c...v_1) + CLOSURE0, // - f closure(f) + CLOSURE1, // - f v closure(f, v) -CALLFUNC,/* b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) */ -CALLFUNC0,/* b v_b...v_1 f - f(v1,...,v_b) */ -CALLFUNC1,/* b v_b...v_1 f r_1 f(v1,...,v_b) */ + CALLFUNC, // b c v_c...v_1 f r_b...r_1 f(v1,...,v_c) + CALLFUNC0, // b v_b...v_1 f - f(v1,...,v_b) + CALLFUNC1, // b v_b...v_1 f r_1 f(v1,...,v_b) -RETCODE,/* b - - */ + RETCODE, // b - - -SETLINE,/* b - - LINE=b */ -SETLINEW,/* w - - LINE=w */ - -POP,/* b - - TOP-=(b+1) */ -POP0,/* - - - TOP-=1 */ -POP1/* - - - TOP-=2 */ + SETLINE, // b - - LINE=b + SETLINEW, // w - - LINE=w + POP, // b - - TOP-=(b+1) + POP0, // - - - TOP-=1 + POP1 // - - - TOP-=2 } OpCode; - -#define RFIELDS_PER_FLUSH 32 /* records (SETMAP) */ -#define LFIELDS_PER_FLUSH 64 /* lists (SETLIST) */ - +#define RFIELDS_PER_FLUSH 32 // records (SETMAP) +#define LFIELDS_PER_FLUSH 64 // lists (SETLIST) #define ZEROVARARG 64 #endif diff --git a/engine/lua/lparser.cpp b/engine/lua/lparser.cpp index 585e01514e0..151c09de920 100644 --- a/engine/lua/lparser.cpp +++ b/engine/lua/lparser.cpp @@ -5,37 +5,33 @@ */ -#include "lauxlib.h" -#include "ldo.h" -#include "lfunc.h" -#include "llex.h" -#include "lmem.h" -#include "lopcodes.h" -#include "lparser.h" -#include "lstate.h" -#include "lstring.h" -#include "lua.h" -#include "luadebug.h" -#include "lzio.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/ldo.h" +#include "engine/lua/lfunc.h" +#include "engine/lua/llex.h" +#include "engine/lua/lmem.h" +#include "engine/lua/lopcodes.h" +#include "engine/lua/lparser.h" +#include "engine/lua/lstate.h" +#include "engine/lua/lstring.h" +#include "engine/lua/lua.h" +#include "engine/lua/luadebug.h" +#include "engine/lua/lzio.h" - -/* for limit numbers in error messages */ +// for limit numbers in error messages #define MES_LIM(x) "(limit=" x ")" - -/* size of a "normal" jump instruction: OpCode + 1 byte */ +// size of a "normal" jump instruction: OpCode + 1 byte #define JMPSIZE 2 -/* maximum number of local variables */ +// maximum number of local variables #define MAXLOCALS 32 #define SMAXLOCALS "32" - -/* maximum number of upvalues */ +// maximum number of upvalues #define MAXUPVALUES 16 #define SMAXUPVALUES "16" - /* ** Variable descriptor: ** must include a "exp" option because LL(1) cannot distinguish @@ -45,14 +41,13 @@ ** VDOT: info is constant index of index name ** VEXP: info is pc index of "nparam" of function call (or 0 if exp is closed) */ -typedef enum {VGLOBAL, VLOCAL, VDOT, VINDEXED, VEXP} varkind; +typedef enum { VGLOBAL, VLOCAL, VDOT, VINDEXED, VEXP } varkind; typedef struct { - varkind k; - int32 info; + varkind k; + int32 info; } vardesc; - /* ** Expression List descriptor: ** tells number of expressions in the list, @@ -60,11 +55,10 @@ typedef struct { ** where is its pc index of "nparam" */ typedef struct { - int32 n; - int32 pc; /* 0 if last expression is closed */ + int32 n; + int32 pc; // 0 if last expression is closed } listdesc; - /* ** Constructors descriptor: ** "n" indicates number of elements, and "k" signals whether @@ -72,789 +66,732 @@ typedef struct { ** or empty (k = ';' or '}') */ typedef struct { - int32 n; - int32 k; + int32 n; + int32 k; } constdesc; - -/* state needed to generate code for a given function */ +// state needed to generate code for a given function typedef struct FuncState { - TProtoFunc *f; /* current function header */ - struct FuncState *prev; /* enclosuring function */ - int32 pc; /* next position to code */ - int32 stacksize; /* number of values on activation register */ - int32 maxstacksize; /* maximum number of values on activation register */ - int32 nlocalvar; /* number of active local variables */ - int32 nupvalues; /* number of upvalues */ - int32 nvars; /* number of entries in f->locvars */ - int32 maxcode; /* size of f->code */ - int32 maxvars; /* size of f->locvars (-1 if no debug information) */ - int32 maxconsts; /* size of f->consts */ - int32 lastsetline; /* line where last SETLINE was issued */ - vardesc upvalues[MAXUPVALUES]; /* upvalues */ - TaggedString *localvar[MAXLOCALS]; /* store local variable names */ + TProtoFunc *f; // current function header + struct FuncState *prev; // enclosuring function + int32 pc; // next position to code + int32 stacksize; // number of values on activation register + int32 maxstacksize; // maximum number of values on activation register + int32 nlocalvar; // number of active local variables + int32 nupvalues; // number of upvalues + int32 nvars; // number of entries in f->locvars + int32 maxcode; // size of f->code + int32 maxvars; // size of f->locvars (-1 if no debug information) + int32 maxconsts; // size of f->consts + int32 lastsetline; // line where last SETLINE was issued + vardesc upvalues[MAXUPVALUES]; // upvalues + TaggedString *localvar[MAXLOCALS]; // store local variable names } FuncState; +static int32 assignment(LexState *ls, vardesc *v, int32 nvars); +static int32 cond(LexState *ls); +static int32 funcname(LexState *ls, vardesc *v); +static int32 funcparams(LexState *ls, int32 slf); +static int32 listfields(LexState *ls); +static int32 localnamelist(LexState *ls); +static int32 optional(LexState *ls, int32 c); +static int32 recfields(LexState *ls); +static int32 stat(LexState *ls); +static void block(LexState *ls); +static void body(LexState *ls, int32 needself, int32 line); +static void chunk(LexState *ls); +static void constructor(LexState *ls); +static void decinit(LexState *ls, listdesc *d); +static void exp0(LexState *ls, vardesc *v); +static void exp1(LexState *ls); +static void exp2(LexState *ls, vardesc *v); +static void explist(LexState *ls, listdesc *e); +static void explist1(LexState *ls, listdesc *e); +static void ifpart(LexState *ls); +static void parlist(LexState *ls); +static void part(LexState *ls, constdesc *cd); +static void recfield(LexState *ls); +static void ret(LexState *ls); +static void simpleexp(LexState *ls, vardesc *v); +static void statlist(LexState *ls); +static void var_or_func(LexState *ls, vardesc *v); +static void var_or_func_tail(LexState *ls, vardesc *v); -static int32 assignment (LexState *ls, vardesc *v, int32 nvars); -static int32 cond (LexState *ls); -static int32 funcname (LexState *ls, vardesc *v); -static int32 funcparams (LexState *ls, int32 slf); -static int32 listfields (LexState *ls); -static int32 localnamelist (LexState *ls); -static int32 optional (LexState *ls, int32 c); -static int32 recfields (LexState *ls); -static int32 stat (LexState *ls); -static void block (LexState *ls); -static void body (LexState *ls, int32 needself, int32 line); -static void chunk (LexState *ls); -static void constructor (LexState *ls); -static void decinit (LexState *ls, listdesc *d); -static void exp0 (LexState *ls, vardesc *v); -static void exp1 (LexState *ls); -static void exp2 (LexState *ls, vardesc *v); -static void explist (LexState *ls, listdesc *e); -static void explist1 (LexState *ls, listdesc *e); -static void ifpart (LexState *ls); -static void parlist (LexState *ls); -static void part (LexState *ls, constdesc *cd); -static void recfield (LexState *ls); -static void ret (LexState *ls); -static void simpleexp (LexState *ls, vardesc *v); -static void statlist (LexState *ls); -static void var_or_func (LexState *ls, vardesc *v); -static void var_or_func_tail (LexState *ls, vardesc *v); - - - -static void check_pc (FuncState *fs, int32 n) { - if (fs->pc+n > fs->maxcode) - fs->maxcode = luaM_growvector(&fs->f->code, fs->maxcode, - Byte, codeEM, MAX_INT); +static void check_pc(FuncState *fs, int32 n) { + if (fs->pc + n > fs->maxcode) + fs->maxcode = luaM_growvector(&fs->f->code, fs->maxcode, byte, codeEM, MAX_INT); } - -static void code_byte (FuncState *fs, Byte c) { - check_pc(fs, 1); - fs->f->code[fs->pc++] = c; +static void code_byte(FuncState *fs, byte c) { + check_pc(fs, 1); + fs->f->code[fs->pc++] = c; } - -static void deltastack (LexState *ls, int32 delta) { - FuncState *fs = ls->fs; - fs->stacksize += delta; - if (fs->stacksize > fs->maxstacksize) { - if (fs->stacksize > 255) - luaX_error(ls, "function/expression too complex"); - fs->maxstacksize = fs->stacksize; - } +static void deltastack(LexState *ls, int32 delta) { + FuncState *fs = ls->fs; + fs->stacksize += delta; + if (fs->stacksize > fs->maxstacksize) { + if (fs->stacksize > 255) + luaX_error(ls, "function/expression too complex"); + fs->maxstacksize = fs->stacksize; + } } - -static int32 code_oparg_at (LexState *ls, int32 pc, OpCode op, int32 builtin, - int32 arg, int32 delta) { - Byte *code = ls->fs->f->code; - deltastack(ls, delta); - if (arg < builtin) { - code[pc] = op+1+arg; - return 1; - } - else if (arg <= 255) { - code[pc] = op; - code[pc+1] = arg; - return 2; - } - else if (arg <= MAX_WORD) { - code[pc] = op+1+builtin; - code[pc+2] = arg>>8; - code[pc+1] = arg&0xFF; - return 3; - } - else luaX_error(ls, "code too long " MES_LIM("64K")); - return 0; /* to avoid warnings */ +static int32 code_oparg_at(LexState *ls, int32 pc, OpCode op, int32 builtin, int32 arg, int32 delta) { + byte *code = ls->fs->f->code; + deltastack(ls, delta); + if (arg < builtin) { + code[pc] = op + 1 + arg; + return 1; + } else if (arg <= 255) { + code[pc] = op; + code[pc + 1] = arg; + return 2; + } else if (arg <= MAX_WORD) { + code[pc] = op + 1 + builtin; + code[pc + 2] = arg >> 8; + code[pc + 1] = arg & 0xFF; + return 3; + } else + luaX_error(ls, "code too long " MES_LIM("64K")); + return 0; // to avoid warnings } - -static int32 fix_opcode (LexState *ls, int32 pc, OpCode op, int32 builtin, int32 arg) { - FuncState *fs = ls->fs; - TProtoFunc *f = fs->f; - if (arg < builtin) { /* close space */ - luaO_memdown(f->code+pc+1, f->code+pc+2, fs->pc-(pc+2)); - fs->pc--; - } - else if (arg > 255) { /* open space */ - check_pc(fs, 1); - luaO_memup(f->code+pc+1, f->code+pc, fs->pc-pc); - fs->pc++; - } - return code_oparg_at(ls, pc, op, builtin, arg, 0) - 2; +static int32 fix_opcode(LexState *ls, int32 pc, OpCode op, int32 builtin, int32 arg) { + FuncState *fs = ls->fs; + TProtoFunc *f = fs->f; + if (arg < builtin) { // close space + luaO_memdown(f->code + pc + 1, f->code + pc + 2, fs->pc - (pc + 2)); + fs->pc--; + } else if (arg > 255) { // open space + check_pc(fs, 1); + luaO_memup(f->code + pc + 1, f->code + pc, fs->pc - pc); + fs->pc++; + } + return code_oparg_at(ls, pc, op, builtin, arg, 0) - 2; } -static void code_oparg (LexState *ls, OpCode op, int32 builtin, int32 arg, - int32 delta) { - check_pc(ls->fs, 3); /* maximum code size */ - ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, builtin, arg, delta); +static void code_oparg(LexState *ls, OpCode op, int32 builtin, int32 arg, int32 delta) { + check_pc(ls->fs, 3); // maximum code size + ls->fs->pc += code_oparg_at(ls, ls->fs->pc, op, builtin, arg, delta); } - -static void code_opcode (LexState *ls, OpCode op, int32 delta) { - deltastack(ls, delta); - code_byte(ls->fs, op); +static void code_opcode(LexState *ls, OpCode op, int32 delta) { + deltastack(ls, delta); + code_byte(ls->fs, op); } - -static void code_constant (LexState *ls, int32 c) { - code_oparg(ls, PUSHCONSTANT, 8, c, 1); +static void code_constant(LexState *ls, int32 c) { + code_oparg(ls, PUSHCONSTANT, 8, c, 1); } - -static int32 next_constant (FuncState *fs) { - TProtoFunc *f = fs->f; - if (f->nconsts >= fs->maxconsts) { - fs->maxconsts = luaM_growvector(&f->consts, fs->maxconsts, TObject, - constantEM, MAX_WORD); - } - return f->nconsts++; +static int32 next_constant(FuncState *fs) { + TProtoFunc *f = fs->f; + if (f->nconsts >= fs->maxconsts) { + fs->maxconsts = luaM_growvector(&f->consts, fs->maxconsts, TObject, constantEM, MAX_WORD); + } + return f->nconsts++; } - -static int32 string_constant (FuncState *fs, TaggedString *s) { - TProtoFunc *f = fs->f; - int32 c = s->constindex; - if (!(c < f->nconsts && - ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) { - c = next_constant(fs); - ttype(&f->consts[c]) = LUA_T_STRING; - tsvalue(&f->consts[c]) = s; - s->constindex = c; /* hint for next time */ - } - return c; +static int32 string_constant(FuncState *fs, TaggedString *s) { + TProtoFunc *f = fs->f; + int32 c = s->constindex; + if (!(c < f->nconsts && ttype(&f->consts[c]) == LUA_T_STRING && tsvalue(&f->consts[c]) == s)) { + c = next_constant(fs); + ttype(&f->consts[c]) = LUA_T_STRING; + tsvalue(&f->consts[c]) = s; + s->constindex = c; // hint for next time + } + return c; } - -static void code_string (LexState *ls, TaggedString *s) { - code_constant(ls, string_constant(ls->fs, s)); +static void code_string(LexState *ls, TaggedString *s) { + code_constant(ls, string_constant(ls->fs, s)); } - #define LIM 20 -static int32 real_constant (FuncState *fs, real r) { - /* check whether 'r' has appeared within the last LIM entries */ - TObject *cnt = fs->f->consts; - int32 c = fs->f->nconsts; - int32 lim = c < LIM ? 0 : c-LIM; - while (--c >= lim) { - if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) - return c; - } - /* not found; create a luaM_new entry */ - c = next_constant(fs); - cnt = fs->f->consts; /* 'next_constant' may reallocate this vector */ - ttype(&cnt[c]) = LUA_T_NUMBER; - nvalue(&cnt[c]) = r; - return c; +static int32 real_constant(FuncState *fs, real r) { + // check whether 'r' has appeared within the last LIM entries + TObject *cnt = fs->f->consts; + int32 c = fs->f->nconsts; + int32 lim = c < LIM ? 0 : c-LIM; + while (--c >= lim) { + if (ttype(&cnt[c]) == LUA_T_NUMBER && nvalue(&cnt[c]) == r) + return c; + } + // not found; create a luaM_new entry + c = next_constant(fs); + cnt = fs->f->consts; // 'next_constant' may reallocate this vector + ttype(&cnt[c]) = LUA_T_NUMBER; + nvalue(&cnt[c]) = r; + return c; } - -static void code_number (LexState *ls, real f) { - int32 i; - if (f >= 0 && f <= (real)MAX_WORD && (real)(i=(int32)f) == f) - code_oparg(ls, PUSHNUMBER, 3, i, 1); /* f has a short integer value */ - else - code_constant(ls, real_constant(ls->fs, f)); +static void code_number(LexState *ls, real f) { + int32 i; + if (f >= 0 && f <= (real)MAX_WORD && (real)(i = (int32)f) == f) + code_oparg(ls, PUSHNUMBER, 3, i, 1); // f has a short integer value + else + code_constant(ls, real_constant(ls->fs, f)); } - -static void flush_record (LexState *ls, int32 n) { - if (n > 0) - code_oparg(ls, SETMAP, 1, n-1, -2*n); +static void flush_record(LexState *ls, int32 n) { + if (n > 0) + code_oparg(ls, SETMAP, 1, n - 1, -2 * n); } - -static void flush_list (LexState *ls, int32 m, int32 n) { - if (n == 0) return; - code_oparg(ls, SETLIST, 1, m, -n); - code_byte(ls->fs, n); +static void flush_list(LexState *ls, int32 m, int32 n) { + if (n == 0) + return; + code_oparg(ls, SETLIST, 1, m, -n); + code_byte(ls->fs, n); } - -static void luaI_registerlocalvar (FuncState *fs, TaggedString *varname, - int32 line) { - if (fs->maxvars != -1) { /* debug information? */ - TProtoFunc *f = fs->f; - if (fs->nvars >= fs->maxvars) - fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars, - LocVar, "", MAX_WORD); - f->locvars[fs->nvars].varname = varname; - f->locvars[fs->nvars].line = line; - fs->nvars++; - } +static void luaI_registerlocalvar(FuncState *fs, TaggedString *varname, int32 line) { + if (fs->maxvars != -1) { // debug information? + TProtoFunc *f = fs->f; + if (fs->nvars >= fs->maxvars) + fs->maxvars = luaM_growvector(&f->locvars, fs->maxvars, LocVar, "", MAX_WORD); + f->locvars[fs->nvars].varname = varname; + f->locvars[fs->nvars].line = line; + fs->nvars++; + } } - -static void luaI_unregisterlocalvar (FuncState *fs, int32 line) { - luaI_registerlocalvar(fs, NULL, line); +static void luaI_unregisterlocalvar(FuncState *fs, int32 line) { + luaI_registerlocalvar(fs, NULL, line); } - -static void store_localvar (LexState *ls, TaggedString *name, int32 n) { - FuncState *fs = ls->fs; - if (fs->nlocalvar+n < MAXLOCALS) - fs->localvar[fs->nlocalvar+n] = name; - else - luaX_error(ls, "too many local variables " MES_LIM(SMAXLOCALS)); - luaI_registerlocalvar(fs, name, ls->linenumber); +static void store_localvar(LexState *ls, TaggedString *name, int32 n) { + FuncState *fs = ls->fs; + if (fs->nlocalvar + n < MAXLOCALS) + fs->localvar[fs->nlocalvar + n] = name; + else + luaX_error(ls, "too many local variables " MES_LIM(SMAXLOCALS)); + luaI_registerlocalvar(fs, name, ls->linenumber); } - -static void add_localvar (LexState *ls, TaggedString *name) { - store_localvar(ls, name, 0); - ls->fs->nlocalvar++; +static void add_localvar(LexState *ls, TaggedString *name) { + store_localvar(ls, name, 0); + ls->fs->nlocalvar++; } - -static int32 aux_localname (FuncState *fs, TaggedString *n) { - int32 i; - for (i=fs->nlocalvar-1; i >= 0; i--) - if (n == fs->localvar[i]) return i; /* local var index */ - return -1; /* not found */ +static int32 aux_localname(FuncState *fs, TaggedString *n) { + int32 i; + for (i = fs->nlocalvar - 1; i >= 0; i--) + if (n == fs->localvar[i]) + return i; // local var index + return -1; // not found } - -static void singlevar (LexState *ls, TaggedString *n, vardesc *var, int32 prev) { - FuncState *fs = prev ? ls->fs->prev : ls->fs; - int32 i = aux_localname(fs, n); - if (i >= 0) { /* local value */ - var->k = VLOCAL; - var->info = i; - } - else { /* check shadowing */ - FuncState *level = fs; - while ((level = level->prev) != NULL) - if (aux_localname(level, n) >= 0) - luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); - var->k = VGLOBAL; - var->info = string_constant(fs, n); - } +static void singlevar(LexState *ls, TaggedString *n, vardesc *var, int32 prev) { + FuncState *fs = prev ? ls->fs->prev : ls->fs; + int32 i = aux_localname(fs, n); + if (i >= 0) { // local value + var->k = VLOCAL; + var->info = i; + } else { // check shadowing + FuncState *level = fs; + while (level = level->prev) + if (aux_localname(level, n) >= 0) + luaX_syntaxerror(ls, "cannot access a variable in outer scope", n->str); + var->k = VGLOBAL; + var->info = string_constant(fs, n); + } } - -static int32 indexupvalue (LexState *ls, TaggedString *n) { - FuncState *fs = ls->fs; - vardesc v; - int32 i; - singlevar(ls, n, &v, 1); - for (i=0; inupvalues; i++) { - if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info) - return i; - } - /* new one */ - if (++(fs->nupvalues) > MAXUPVALUES) - luaX_error(ls, "too many upvalues in a single function " - MES_LIM(SMAXUPVALUES)); - fs->upvalues[i] = v; /* i = fs->nupvalues - 1 */ - return i; +static int32 indexupvalue(LexState *ls, TaggedString *n) { + FuncState *fs = ls->fs; + vardesc v; + int32 i; + singlevar(ls, n, &v, 1); + for (i = 0; i < fs->nupvalues; i++) { + if (fs->upvalues[i].k == v.k && fs->upvalues[i].info == v.info) + return i; + } + // new one + if (++(fs->nupvalues) > MAXUPVALUES) + luaX_error(ls, "too many upvalues in a single function " MES_LIM(SMAXUPVALUES)); + fs->upvalues[i] = v; // i = fs->nupvalues - 1 + return i; } - -static void pushupvalue (LexState *ls, TaggedString *n) { - int32 i; - if (ls->fs->prev == NULL) - luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); - if (aux_localname(ls->fs, n) >= 0) - luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); - i = indexupvalue(ls, n); - code_oparg(ls, PUSHUPVALUE, 2, i, 1); +static void pushupvalue(LexState *ls, TaggedString *n) { + int32 i; + if (!ls->fs->prev) + luaX_syntaxerror(ls, "cannot access upvalue in main", n->str); + if (aux_localname(ls->fs, n) >= 0) + luaX_syntaxerror(ls, "cannot access an upvalue in current scope", n->str); + i = indexupvalue(ls, n); + code_oparg(ls, PUSHUPVALUE, 2, i, 1); } - - -static void check_debugline (LexState *ls) { - if (lua_debug && ls->linenumber != ls->fs->lastsetline) { - code_oparg(ls, SETLINE, 0, ls->linenumber, 0); - ls->fs->lastsetline = ls->linenumber; - } +static void check_debugline(LexState *ls) { + if (lua_debug && ls->linenumber != ls->fs->lastsetline) { + code_oparg(ls, SETLINE, 0, ls->linenumber, 0); + ls->fs->lastsetline = ls->linenumber; + } } - -static void adjuststack (LexState *ls, int32 n) { - if (n > 0) - code_oparg(ls, POP, 2, n-1, -n); - else if (n < 0) - code_oparg(ls, PUSHNIL, 1, (-n)-1, -n); +static void adjuststack(LexState *ls, int32 n) { + if (n > 0) + code_oparg(ls, POP, 2, n - 1, -n); + else if (n < 0) + code_oparg(ls, PUSHNIL, 1, (-n) - 1, -n); } - -static void close_exp (LexState *ls, int32 pc, int32 nresults) { - if (pc > 0) { /* expression is an open function call */ - Byte *code = ls->fs->f->code; - int32 nparams = code[pc]; /* save nparams */ - pc += fix_opcode(ls, pc-2, CALLFUNC, 2, nresults); - code[pc] = nparams; /* restore nparams */ - if (nresults != MULT_RET) - deltastack(ls, nresults); /* "push" results */ - deltastack(ls, -(nparams+1)); /* "pop" params and function */ - } +static void close_exp(LexState *ls, int32 pc, int32 nresults) { + if (pc > 0) { // expression is an open function call + byte *code = ls->fs->f->code; + int32 nparams = code[pc]; // save nparams + pc += fix_opcode(ls, pc - 2, CALLFUNC, 2, nresults); + code[pc] = nparams; // restore nparams + if (nresults != MULT_RET) + deltastack(ls, nresults); // "push" results + deltastack(ls, -(nparams + 1)); // "pop" params and function + } } - -static void adjust_mult_assign (LexState *ls, int32 nvars, listdesc *d) { - int32 diff = d->n - nvars; - if (d->pc == 0) { /* list is closed */ - /* push or pop eventual difference between list lengths */ - adjuststack(ls, diff); - } - else { /* must correct function call */ - diff--; /* do not count function call itself */ - if (diff < 0) { /* more variables than values */ - /* function call must provide extra values */ - close_exp(ls, d->pc, -diff); - } - else { /* more values than variables */ - close_exp(ls, d->pc, 0); /* call should provide no value */ - adjuststack(ls, diff); /* pop eventual extra values */ - } - } +static void adjust_mult_assign(LexState *ls, int32 nvars, listdesc *d) { + int32 diff = d->n - nvars; + if (d->pc == 0) { // list is closed + // push or pop eventual difference between list lengths + adjuststack(ls, diff); + } else { // must correct function call + diff--; // do not count function call itself + if (diff < 0) { // more variables than values + // function call must provide extra values + close_exp(ls, d->pc, -diff); + } else { // more values than variables + close_exp(ls, d->pc, 0); // call should provide no value + adjuststack(ls, diff); // pop eventual extra values + } + } } - -static void code_args (LexState *ls, int32 nparams, int32 dots) { - FuncState *fs = ls->fs; - fs->nlocalvar += nparams; /* "self" may already be there */ - nparams = fs->nlocalvar; - if (!dots) { - fs->f->code[1] = nparams; /* fill-in arg information */ - deltastack(ls, nparams); - } - else { - fs->f->code[1] = nparams+ZEROVARARG; - deltastack(ls, nparams+1); - add_localvar(ls, luaS_new("arg")); - } +static void code_args(LexState *ls, int32 nparams, int32 dots) { + FuncState *fs = ls->fs; + fs->nlocalvar += nparams; // "self" may already be there + nparams = fs->nlocalvar; + if (!dots) { + fs->f->code[1] = nparams; // fill-in arg information + deltastack(ls, nparams); + } else { + fs->f->code[1] = nparams + ZEROVARARG; + deltastack(ls, nparams + 1); + add_localvar(ls, luaS_new("arg")); + } } - -static void lua_pushvar (LexState *ls, vardesc *var) { - switch (var->k) { - case VLOCAL: - code_oparg(ls, PUSHLOCAL, 8, var->info, 1); - break; - case VGLOBAL: - code_oparg(ls, GETGLOBAL, 8, var->info, 1); - break; - case VDOT: - code_oparg(ls, GETDOTTED, 8, var->info, 0); - break; - case VINDEXED: - code_opcode(ls, GETTABLE, -1); - break; - case VEXP: - close_exp(ls, var->info, 1); /* function must return 1 value */ - break; - } - var->k = VEXP; - var->info = 0; /* now this is a closed expression */ +static void lua_pushvar(LexState *ls, vardesc *var) { + switch (var->k) { + case VLOCAL: + code_oparg(ls, PUSHLOCAL, 8, var->info, 1); + break; + case VGLOBAL: + code_oparg(ls, GETGLOBAL, 8, var->info, 1); + break; + case VDOT: + code_oparg(ls, GETDOTTED, 8, var->info, 0); + break; + case VINDEXED: + code_opcode(ls, GETTABLE, -1); + break; + case VEXP: + close_exp(ls, var->info, 1); // function must return 1 value + break; + } + var->k = VEXP; + var->info = 0; // now this is a closed expression } - static void storevar (LexState *ls, vardesc *var) { - switch (var->k) { - case VLOCAL: - code_oparg(ls, SETLOCAL, 8, var->info, -1); - break; - case VGLOBAL: - code_oparg(ls, SETGLOBAL, 8, var->info, -1); - break; - case VINDEXED: - code_opcode(ls, SETTABLE0, -3); - break; - default: - LUA_INTERNALERROR("invalid var kind to store"); - } + switch (var->k) { + case VLOCAL: + code_oparg(ls, SETLOCAL, 8, var->info, -1); + break; + case VGLOBAL: + code_oparg(ls, SETGLOBAL, 8, var->info, -1); + break; + case VINDEXED: + code_opcode(ls, SETTABLE0, -3); + break; + default: + LUA_INTERNALERROR("invalid var kind to store"); + } } - -static int32 fixJump (LexState *ls, int32 pc, OpCode op, int32 n) { - /* jump is relative to position following jump instruction */ - return fix_opcode(ls, pc, op, 0, n-(pc+JMPSIZE)); +static int32 fixJump(LexState *ls, int32 pc, OpCode op, int32 n) { + // jump is relative to position following jump instruction + return fix_opcode(ls, pc, op, 0, n - (pc + JMPSIZE)); } - -static void fix_upjmp (LexState *ls, OpCode op, int32 pos) { - int32 delta = ls->fs->pc+JMPSIZE - pos; /* jump is relative */ - if (delta > 255) delta++; - code_oparg(ls, op, 0, delta, 0); +static void fix_upjmp(LexState *ls, OpCode op, int32 pos) { + int32 delta = ls->fs->pc + JMPSIZE - pos; // jump is relative + if (delta > 255) + delta++; + code_oparg(ls, op, 0, delta, 0); } - -static void codeIf (LexState *ls, int32 thenAdd, int32 elseAdd) { - FuncState *fs = ls->fs; - int32 elseinit = elseAdd+JMPSIZE; - if (fs->pc == elseinit) { /* no else part */ - fs->pc -= JMPSIZE; - elseinit = fs->pc; - } - else - elseinit += fixJump(ls, elseAdd, JMP, fs->pc); - fixJump(ls, thenAdd, IFFJMP, elseinit); +static void codeIf(LexState *ls, int32 thenAdd, int32 elseAdd) { + FuncState *fs = ls->fs; + int32 elseinit = elseAdd + JMPSIZE; + if (fs->pc == elseinit) { // no else part + fs->pc -= JMPSIZE; + elseinit = fs->pc; + } else + elseinit += fixJump(ls, elseAdd, JMP, fs->pc); + fixJump(ls, thenAdd, IFFJMP, elseinit); } - -static void func_onstack (LexState *ls, FuncState *func) { - FuncState *fs = ls->fs; - int32 i; - int32 c = next_constant(fs); - ttype(&fs->f->consts[c]) = LUA_T_PROTO; - fs->f->consts[c].value.tf = func->f; - if (func->nupvalues == 0) - code_constant(ls, c); - else { - for (i=0; inupvalues; i++) - lua_pushvar(ls, &func->upvalues[i]); - code_oparg(ls, CLOSURE, 0, c, -func->nupvalues+1); - code_byte(fs, func->nupvalues); - } +static void func_onstack(LexState *ls, FuncState *func) { + FuncState *fs = ls->fs; + int32 i; + int32 c = next_constant(fs); + ttype(&fs->f->consts[c]) = LUA_T_PROTO; + fs->f->consts[c].value.tf = func->f; + if (func->nupvalues == 0) + code_constant(ls, c); + else { + for (i = 0; i < func->nupvalues; i++) + lua_pushvar(ls, &func->upvalues[i]); + code_oparg(ls, CLOSURE, 0, c, -func->nupvalues + 1); + code_byte(fs, func->nupvalues); + } } - -static void init_state (LexState *ls, FuncState *fs, TaggedString *filename) { - TProtoFunc *f = luaF_newproto(); - fs->prev = ls->fs; /* linked list of funcstates */ - ls->fs = fs; - fs->stacksize = 0; - fs->maxstacksize = 0; - fs->nlocalvar = 0; - fs->nupvalues = 0; - fs->lastsetline = 0; - fs->f = f; - f->fileName = filename; - fs->pc = 0; - fs->maxcode = 0; - f->code = NULL; - fs->maxconsts = 0; - if (lua_debug) - fs->nvars = fs->maxvars = 0; - else - fs->maxvars = -1; /* flag no debug information */ - code_byte(fs, 0); /* to be filled with stacksize */ - code_byte(fs, 0); /* to be filled with arg information */ +static void init_state(LexState *ls, FuncState *fs, TaggedString *filename) { + TProtoFunc *f = luaF_newproto(); + fs->prev = ls->fs; // linked list of funcstates + ls->fs = fs; + fs->stacksize = 0; + fs->maxstacksize = 0; + fs->nlocalvar = 0; + fs->nupvalues = 0; + fs->lastsetline = 0; + fs->f = f; + f->fileName = filename; + fs->pc = 0; + fs->maxcode = 0; + f->code = NULL; + fs->maxconsts = 0; + if (lua_debug) + fs->nvars = fs->maxvars = 0; + else + fs->maxvars = -1; // flag no debug information + code_byte(fs, 0); // to be filled with stacksize + code_byte(fs, 0); // to be filled with arg information } - -static void close_func (LexState *ls) { - FuncState *fs = ls->fs; - TProtoFunc *f = fs->f; - code_opcode(ls, ENDCODE, 0); - f->code[0] = fs->maxstacksize; - f->code = luaM_reallocvector(f->code, fs->pc, Byte); - f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); - if (fs->maxvars != -1) { /* debug information? */ - luaI_registerlocalvar(fs, NULL, -1); /* flag end of vector */ - f->locvars = luaM_reallocvector(f->locvars, fs->nvars, LocVar); - } - ls->fs = fs->prev; +static void close_func(LexState *ls) { + FuncState *fs = ls->fs; + TProtoFunc *f = fs->f; + code_opcode(ls, ENDCODE, 0); + f->code[0] = fs->maxstacksize; + f->code = luaM_reallocvector(f->code, fs->pc, byte); + f->consts = luaM_reallocvector(f->consts, f->nconsts, TObject); + if (fs->maxvars != -1) { // debug information? + luaI_registerlocalvar(fs, NULL, -1); // flag end of vector + f->locvars = luaM_reallocvector(f->locvars, fs->nvars, LocVar); + } + ls->fs = fs->prev; } - - -static int32 expfollow [] = {ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME, - LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0}; +static int32 expfollow [] = { ELSE, ELSEIF, THEN, IF, WHILE, REPEAT, DO, NAME, + LOCAL, FUNCTION, END, UNTIL, RETURN, ')', ']', '}', ';', EOS, ',', 0 +}; static int32 is_in (int32 tok, int32 *toks) { - int32 *t = toks; - while (*t) { - if (*t == tok) - return t-toks; - t++; - } - return -1; + int32 *t = toks; + while (*t) { + if (*t == tok) + return + t-toks; + t++; + } + return -1; } - -static void next (LexState *ls) { - ls->token = luaX_lex(ls); +static void next(LexState *ls) { + ls->token = luaX_lex(ls); } +static void error_expected(LexState *ls, int32 token) { + char buff[100], t[TOKEN_LEN]; -static void error_expected (LexState *ls, int32 token) { - char buff[100], t[TOKEN_LEN]; - luaX_token2str(ls, token, t); - sprintf(buff, "`%s' expected", t); - luaX_error(ls, buff); + luaX_token2str(ls, token, t); + sprintf(buff, "`%s' expected", t); + luaX_error(ls, buff); } -static void error_unmatched (LexState *ls, int32 what, int32 who, int32 where) { - if (where == ls->linenumber) - error_expected(ls, what); - else { - char buff[100]; - char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; - luaX_token2str(ls, what, t_what); - luaX_token2str(ls, who, t_who); - sprintf(buff, "`%s' expected (to close `%s' at line %d)", - t_what, t_who, (int)where); - luaX_error(ls, buff); - } +static void error_unmatched(LexState *ls, int32 what, int32 who, int32 where) { + if (where == ls->linenumber) + error_expected(ls, what); + else { + char buff[100]; + char t_what[TOKEN_LEN], t_who[TOKEN_LEN]; + luaX_token2str(ls, what, t_what); + luaX_token2str(ls, who, t_who); + sprintf(buff, "`%s' expected (to close `%s' at line %d)", t_what, t_who, (int)where); + luaX_error(ls, buff); + } } -static void check (LexState *ls, int32 c) { - if (ls->token != c) - error_expected(ls, c); - next(ls); +static void check(LexState *ls, int32 c) { + if (ls->token != c) + error_expected(ls, c); + next(ls); } -static void check_match (LexState *ls, int32 what, int32 who, int32 where) { - if (ls->token != what) - error_unmatched(ls, what, who, where); - check_debugline(ls); /* to 'mark' the 'what' */ - next(ls); +static void check_match(LexState *ls, int32 what, int32 who, int32 where) { + if (ls->token != what) + error_unmatched(ls, what, who, where); + check_debugline(ls); // to 'mark' the 'what' + next(ls); } -static TaggedString *checkname (LexState *ls) { - TaggedString *ts; - if (ls->token != NAME) - luaX_error(ls, "`NAME' expected"); - ts = ls->seminfo.ts; - next(ls); - return ts; +static TaggedString *checkname(LexState *ls) { + TaggedString *ts; + if (ls->token != NAME) + luaX_error(ls, "`NAME' expected"); + ts = ls->seminfo.ts; + next(ls); + return ts; } - -static int32 optional (LexState *ls, int32 c) { - if (ls->token == c) { - next(ls); - return 1; - } - else return 0; +static int32 optional(LexState *ls, int32 c) { + if (ls->token == c) { + next(ls); + return 1; + } else + return 0; } - TProtoFunc *luaY_parser (ZIO *z) { - struct LexState lexstate; - struct FuncState funcstate; - luaX_setinput(&lexstate, z); - init_state(&lexstate, &funcstate, luaS_new(zname(z))); - next(&lexstate); /* read first token */ - chunk(&lexstate); - if (lexstate.token != EOS) - luaX_error(&lexstate, " expected"); - close_func(&lexstate); - return funcstate.f; + LexState lexstate; + FuncState funcstate; + luaX_setinput(&lexstate, z); + init_state(&lexstate, &funcstate, luaS_new(zname(z))); + next(&lexstate); // read first token + chunk(&lexstate); + if (lexstate.token != EOS) + luaX_error(&lexstate, " expected"); + close_func(&lexstate); + return funcstate.f; } - - /*============================================================*/ /* GRAMAR RULES */ /*============================================================*/ -static void chunk (LexState *ls) { - /* chunk -> statlist ret */ - statlist(ls); - ret(ls); +static void chunk(LexState *ls) { + // chunk -> statlist ret + statlist(ls); + ret(ls); } -static void statlist (LexState *ls) { - /* statlist -> { stat [;] } */ - while (stat(ls)) { - LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar, - "stack size != # local vars"); - optional(ls, ';'); - } +static void statlist(LexState *ls) { + // statlist -> { stat [;] } + while (stat(ls)) { + LUA_ASSERT(ls->fs->stacksize == ls->fs->nlocalvar, "stack size != # local vars"); + optional(ls, ';'); + } } -static int32 stat (LexState *ls) { - int32 line = ls->linenumber; /* may be needed for error messages */ - FuncState *fs = ls->fs; - switch (ls->token) { - case IF: { /* stat -> IF ifpart END */ - next(ls); - ifpart(ls); - check_match(ls, END, IF, line); - return 1; - } - - case WHILE: { /* stat -> WHILE cond DO block END */ - TProtoFunc *f = fs->f; - int32 while_init = fs->pc; - int32 cond_end, cond_size; - next(ls); - cond_end = cond(ls); - check(ls, DO); - block(ls); - check_match(ls, END, WHILE, line); - cond_size = cond_end-while_init; - check_pc(fs, cond_size); - memcpy(f->code+fs->pc, f->code+while_init, cond_size); - luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); - while_init += JMPSIZE + fixJump(ls, while_init, JMP, fs->pc-cond_size); - fix_upjmp(ls, IFTUPJMP, while_init); - return 1; - } - - case DO: { /* stat -> DO block END */ - next(ls); - block(ls); - check_match(ls, END, DO, line); - return 1; - } - - case REPEAT: { /* stat -> REPEAT block UNTIL exp1 */ - int32 repeat_init = fs->pc; - next(ls); - block(ls); - check_match(ls, UNTIL, REPEAT, line); - exp1(ls); - fix_upjmp(ls, IFFUPJMP, repeat_init); - deltastack(ls, -1); /* pops condition */ - return 1; - } - - case FUNCTION: { /* stat -> FUNCTION funcname body */ - int32 needself; - vardesc v; - if (ls->fs->prev) /* inside other function? */ - return 0; - check_debugline(ls); - next(ls); - needself = funcname(ls, &v); - body(ls, needself, line); - storevar(ls, &v); - return 1; - } - - case LOCAL: { /* stat -> LOCAL localnamelist decinit */ - listdesc d; - int32 nvars; - check_debugline(ls); - next(ls); - nvars = localnamelist(ls); - decinit(ls, &d); - ls->fs->nlocalvar += nvars; - adjust_mult_assign(ls, nvars, &d); - return 1; - } - - case NAME: case '%': { /* stat -> func | ['%'] NAME assignment */ - vardesc v; - check_debugline(ls); - var_or_func(ls, &v); - if (v.k == VEXP) { /* stat -> func */ - if (v.info == 0) /* is just an upper value? */ - luaX_error(ls, "syntax error"); - close_exp(ls, v.info, 0); - } - else { - int32 left = assignment(ls, &v, 1); /* stat -> ['%'] NAME assignment */ - adjuststack(ls, left); /* remove eventual 'garbage' left on stack */ - } - return 1; - } - - case RETURN: case ';': case ELSE: case ELSEIF: - case END: case UNTIL: case EOS: /* 'stat' follow */ - return 0; - - default: - luaX_error(ls, " expected"); - return 0; /* to avoid warnings */ - } +static int32 stat(LexState *ls) { + int32 line = ls->linenumber; // may be needed for error messages + FuncState *fs = ls->fs; + switch (ls->token) { + case IF: + { // stat -> IF ifpart END + next(ls); + ifpart(ls); + check_match(ls, END, IF, line); + return 1; + } + case WHILE: + { // stat -> WHILE cond DO block END + TProtoFunc *f = fs->f; + int32 while_init = fs->pc; + int32 cond_end, cond_size; + next(ls); + cond_end = cond(ls); + check(ls, DO); + block(ls); + check_match(ls, END, WHILE, line); + cond_size = cond_end-while_init; + check_pc(fs, cond_size); + memcpy(f->code+fs->pc, f->code+while_init, cond_size); + luaO_memdown(f->code+while_init, f->code+cond_end, fs->pc-while_init); + while_init += JMPSIZE + fixJump(ls, while_init, JMP, fs->pc-cond_size); + fix_upjmp(ls, IFTUPJMP, while_init); + return 1; + } + case DO: + { // stat -> DO block END + next(ls); + block(ls); + check_match(ls, END, DO, line); + return 1; + } + case REPEAT: + { // stat -> REPEAT block UNTIL exp1 + int32 repeat_init = fs->pc; + next(ls); + block(ls); + check_match(ls, UNTIL, REPEAT, line); + exp1(ls); + fix_upjmp(ls, IFFUPJMP, repeat_init); + deltastack(ls, -1); // pops condition + return 1; + } + case FUNCTION: + { // stat -> FUNCTION funcname body + int32 needself; + vardesc v; + if (ls->fs->prev) // inside other function? + return 0; + check_debugline(ls); + next(ls); + needself = funcname(ls, &v); + body(ls, needself, line); + storevar(ls, &v); + return 1; + } + case LOCAL: + { // stat -> LOCAL localnamelist decinit + listdesc d; + int32 nvars; + check_debugline(ls); + next(ls); + nvars = localnamelist(ls); + decinit(ls, &d); + ls->fs->nlocalvar += nvars; + adjust_mult_assign(ls, nvars, &d); + return 1; + } + case NAME: + case '%': + { // stat -> func | ['%'] NAME assignment + vardesc v; + check_debugline(ls); + var_or_func(ls, &v); + if (v.k == VEXP) { // stat -> func + if (v.info == 0) // is just an upper value? + luaX_error(ls, "syntax error"); + close_exp(ls, v.info, 0); + } else { + int32 left = assignment(ls, &v, 1); // stat -> ['%'] NAME assignment + adjuststack(ls, left); // remove eventual 'garbage' left on stack + } + return 1; + } + case RETURN: + case ';': + case ELSE: + case ELSEIF: + case END: + case UNTIL: + case EOS: // 'stat' follow + return 0; + default: + luaX_error(ls, " expected"); + return 0; // to avoid warnings + } } -static int32 SaveWord (LexState *ls) { - int32 res = ls->fs->pc; - check_pc(ls->fs, JMPSIZE); - ls->fs->pc += JMPSIZE; /* open space */ - return res; +static int32 SaveWord(LexState *ls) { + int32 res = ls->fs->pc; + check_pc(ls->fs, JMPSIZE); + ls->fs->pc += JMPSIZE; // open space + return res; } -static int32 SaveWordPop (LexState *ls) { - deltastack(ls, -1); /* pop condition */ - return SaveWord(ls); +static int32 SaveWordPop(LexState *ls) { + deltastack(ls, -1); // pop condition + return SaveWord(ls); } -static int32 cond (LexState *ls) { - /* cond -> exp1 */ - exp1(ls); - return SaveWordPop(ls); +static int32 cond(LexState *ls) { + // cond -> exp1 + exp1(ls); + return SaveWordPop(ls); } -static void block (LexState *ls) { - /* block -> chunk */ - FuncState *fs = ls->fs; - int32 nlocalvar = fs->nlocalvar; - chunk(ls); - adjuststack(ls, fs->nlocalvar - nlocalvar); - for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) - luaI_unregisterlocalvar(fs, ls->linenumber); +static void block(LexState *ls) { + // block -> chunk + FuncState *fs = ls->fs; + int32 nlocalvar = fs->nlocalvar; + chunk(ls); + adjuststack(ls, fs->nlocalvar - nlocalvar); + for (; fs->nlocalvar > nlocalvar; fs->nlocalvar--) + luaI_unregisterlocalvar(fs, ls->linenumber); } -static int32 funcname (LexState *ls, vardesc *v) { - /* funcname -> NAME [':' NAME | '.' NAME] */ - int32 needself = 0; - singlevar(ls, checkname(ls), v, 0); - if (ls->token == ':' || ls->token == '.') { - needself = (ls->token == ':'); - next(ls); - lua_pushvar(ls, v); - code_string(ls, checkname(ls)); - v->k = VINDEXED; - } - return needself; +static int32 funcname(LexState *ls, vardesc *v) { + // funcname -> NAME [':' NAME | '.' NAME] + int32 needself = 0; + singlevar(ls, checkname(ls), v, 0); + if (ls->token == ':' || ls->token == '.') { + needself = (ls->token == ':'); + next(ls); + lua_pushvar(ls, v); + code_string(ls, checkname(ls)); + v->k = VINDEXED; + } + return needself; } -static void body (LexState *ls, int32 needself, int32 line) { - /* body -> '(' parlist ')' chunk END */ - FuncState newfs; - init_state(ls, &newfs, ls->fs->f->fileName); - newfs.f->lineDefined = line; - check(ls, '('); - if (needself) - add_localvar(ls, luaS_new("self")); - parlist(ls); - check(ls, ')'); - chunk(ls); - check_match(ls, END, FUNCTION, line); - close_func(ls); - func_onstack(ls, &newfs); +static void body(LexState *ls, int32 needself, int32 line) { + // body -> '(' parlist ')' chunk END */ + FuncState newfs; + init_state(ls, &newfs, ls->fs->f->fileName); + newfs.f->lineDefined = line; + check(ls, '('); + if (needself) + add_localvar(ls, luaS_new("self")); + parlist(ls); + check(ls, ')'); + chunk(ls); + check_match(ls, END, FUNCTION, line); + close_func(ls); + func_onstack(ls, &newfs); } -static void ifpart (LexState *ls) { - /* ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] */ - int32 c = cond(ls); - int32 e; - check(ls, THEN); - block(ls); - e = SaveWord(ls); - switch (ls->token) { - case ELSE: - next(ls); - block(ls); - break; - - case ELSEIF: - next(ls); - ifpart(ls); - break; - } - codeIf(ls, c, e); +static void ifpart(LexState *ls) { + // ifpart -> cond THEN block [ELSE block | ELSEIF ifpart] + int32 c = cond(ls); + int32 e; + check(ls, THEN); + block(ls); + e = SaveWord(ls); + switch (ls->token) { + case ELSE: + next(ls); + block(ls); + break; + case ELSEIF: + next(ls); + ifpart(ls); + break; + } + codeIf(ls, c, e); } static void ret (LexState *ls) { - /* ret -> [RETURN explist sc] */ - if (ls->token == RETURN) { - listdesc e; - check_debugline(ls); - next(ls); - explist(ls, &e); - close_exp(ls, e.pc, MULT_RET); - code_oparg(ls, RETCODE, 0, ls->fs->nlocalvar, 0); - ls->fs->stacksize = ls->fs->nlocalvar; /* removes all temp values */ - optional(ls, ';'); - } + // ret -> [RETURN explist sc] + if (ls->token == RETURN) { + listdesc e; + check_debugline(ls); + next(ls); + explist(ls, &e); + close_exp(ls, e.pc, MULT_RET); + code_oparg(ls, RETCODE, 0, ls->fs->nlocalvar, 0); + ls->fs->stacksize = ls->fs->nlocalvar; // removes all temp values + optional(ls, ';'); + } } - /* ** For parsing expressions, we use a classic stack with priorities. ** Each binary operator is represented by its index in "binop" + FIRSTBIN @@ -869,463 +806,448 @@ static void ret (LexState *ls) { */ #define POW 13 -static int32 binop [] = {EQ, NE, '>', '<', LE, GE, CONC, - '+', '-', '*', '/', '^', 0}; +static int32 binop [] = { EQ, NE, '>', '<', LE, GE, CONC, '+', '-', '*', '/', '^', 0 }; -static int32 priority [POW+1] = {5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6}; +static int32 priority [POW + 1] = { 5, 5, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 4, 6 }; -static OpCode opcodes [POW+1] = {NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, - LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP}; +static OpCode opcodes [POW + 1] = { NOTOP, MINUSOP, EQOP, NEQOP, GTOP, LTOP, + LEOP, GEOP, CONCOP, ADDOP, SUBOP, MULTOP, DIVOP, POWOP }; #define MAXOPS 20 typedef struct { - int32 ops[MAXOPS]; - int32 top; + int32 ops[MAXOPS]; + int32 top; } stack_op; - -static void exp1 (LexState *ls) { - vardesc v; - exp0(ls, &v); - lua_pushvar(ls, &v); - if (is_in(ls->token, expfollow) < 0) - luaX_error(ls, "ill formed expression"); +static void exp1(LexState *ls) { + vardesc v; + exp0(ls, &v); + lua_pushvar(ls, &v); + if (is_in(ls->token, expfollow) < 0) + luaX_error(ls, "ill formed expression"); } - -static void exp0 (LexState *ls, vardesc *v) { - exp2(ls, v); - while (ls->token == AND || ls->token == OR) { - int32 is_and = (ls->token == AND); - int32 pc; - lua_pushvar(ls, v); - next(ls); - pc = SaveWordPop(ls); - exp2(ls, v); - lua_pushvar(ls, v); - fixJump(ls, pc, (is_and?ONFJMP:ONTJMP), ls->fs->pc); - } +static void exp0(LexState *ls, vardesc *v) { + exp2(ls, v); + while (ls->token == AND || ls->token == OR) { + int32 is_and = (ls->token == AND); + int32 pc; + lua_pushvar(ls, v); + next(ls); + pc = SaveWordPop(ls); + exp2(ls, v); + lua_pushvar(ls, v); + fixJump(ls, pc, (is_and ? ONFJMP: ONTJMP), ls->fs->pc); + } } - -static void push (LexState *ls, stack_op *s, int32 op) { - if (s->top == MAXOPS) - luaX_error(ls, "expression too complex"); - s->ops[s->top++] = op; +static void push(LexState *ls, stack_op *s, int32 op) { + if (s->top == MAXOPS) + luaX_error(ls, "expression too complex"); + s->ops[s->top++] = op; } - -static void prefix (LexState *ls, stack_op *s) { - while (ls->token == NOT || ls->token == '-') { - push(ls, s, ls->token==NOT?0:1); - next(ls); - } +static void prefix(LexState *ls, stack_op *s) { + while (ls->token == NOT || ls->token == '-') { + push(ls, s, ls->token == NOT ? 0 : 1); + next(ls); + } } static void pop_to (LexState *ls, stack_op *s, int32 prio) { - int32 op; - while (s->top > 0 && priority[(op=s->ops[s->top-1])] >= prio) { - code_opcode(ls, opcodes[op], optop--; - } + int32 op; + while (s->top > 0 && priority[(op = s->ops[s->top - 1])] >= prio) { + code_opcode(ls, opcodes[op], op < FIRSTBIN ? 0: -1); + s->top--; + } } static void exp2 (LexState *ls, vardesc *v) { - stack_op s; - int32 op; - s.top = 0; - prefix(ls, &s); - simpleexp(ls, v); - while ((op = is_in(ls->token, binop)) >= 0) { - op += FIRSTBIN; - lua_pushvar(ls, v); - /* '^' is right associative, so must 'simulate' a higher priority */ - pop_to(ls, &s, (op == POW)?priority[op]+1:priority[op]); - push(ls, &s, op); - next(ls); - prefix(ls, &s); - simpleexp(ls, v); - lua_pushvar(ls, v); - } - if (s.top > 0) { - lua_pushvar(ls, v); - pop_to(ls, &s, 0); - } + stack_op s; + int32 op; + s.top = 0; + prefix(ls, &s); + simpleexp(ls, v); + while ((op = is_in(ls->token, binop)) >= 0) { + op += FIRSTBIN; + lua_pushvar(ls, v); + // '^' is right associative, so must 'simulate' a higher priority + pop_to(ls, &s, (op == POW) ? priority[op] + 1 : priority[op]); + push(ls, &s, op); + next(ls); + prefix(ls, &s); + simpleexp(ls, v); + lua_pushvar(ls, v); + } + if (s.top > 0) { + lua_pushvar(ls, v); + pop_to(ls, &s, 0); + } } - -static void simpleexp (LexState *ls, vardesc *v) { - check_debugline(ls); - switch (ls->token) { - case '(': /* simpleexp -> '(' exp0 ')' */ - next(ls); - exp0(ls, v); - check(ls, ')'); - break; - - case NUMBER: /* simpleexp -> NUMBER */ - code_number(ls, ls->seminfo.r); - next(ls); - v->k = VEXP; v->info = 0; - break; - - case STRING: /* simpleexp -> STRING */ - code_string(ls, ls->seminfo.ts); - next(ls); - v->k = VEXP; v->info = 0; - break; - - case NIL: /* simpleexp -> NIL */ - adjuststack(ls, -1); - next(ls); - v->k = VEXP; v->info = 0; - break; - - case '{': /* simpleexp -> constructor */ - constructor(ls); - v->k = VEXP; v->info = 0; - break; - - case FUNCTION: { /* simpleexp -> FUNCTION body */ - int32 line = ls->linenumber; - next(ls); - body(ls, 0, line); - v->k = VEXP; v->info = 0; - break; - } - - case NAME: case '%': - var_or_func(ls, v); - break; - - default: - luaX_error(ls, " expected"); - break; - } +static void simpleexp(LexState *ls, vardesc *v) { + check_debugline(ls); + switch (ls->token) { + case '(': // simpleexp -> '(' exp0 ')' + next(ls); + exp0(ls, v); + check(ls, ')'); + break; + case NUMBER: // simpleexp -> NUMBER + code_number(ls, ls->seminfo.r); + next(ls); + v->k = VEXP; + v->info = 0; + break; + case STRING: // simpleexp -> STRING + code_string(ls, ls->seminfo.ts); + next(ls); + v->k = VEXP; + v->info = 0; + break; + case NIL: // simpleexp -> NIL + adjuststack(ls, -1); + next(ls); + v->k = VEXP; + v->info = 0; + break; + case '{': // simpleexp -> constructor + constructor(ls); + v->k = VEXP; + v->info = 0; + break; + case FUNCTION: + { // simpleexp -> FUNCTION body + int32 line = ls->linenumber; + next(ls); + body(ls, 0, line); + v->k = VEXP; v->info = 0; + break; + } + case NAME: + case '%': + var_or_func(ls, v); + break; + default: + luaX_error(ls, " expected"); + break; + } } -static void var_or_func (LexState *ls, vardesc *v) { - /* var_or_func -> ['%'] NAME var_or_func_tail */ - if (optional(ls, '%')) { /* upvalue? */ - pushupvalue(ls, checkname(ls)); - v->k = VEXP; - v->info = 0; /* closed expression */ - } - else /* variable name */ - singlevar(ls, checkname(ls), v, 0); - var_or_func_tail(ls, v); +static void var_or_func(LexState *ls, vardesc *v) { + // var_or_func -> ['%'] NAME var_or_func_tail + if (optional(ls, '%')) { // upvalue? + pushupvalue(ls, checkname(ls)); + v->k = VEXP; + v->info = 0; // closed expression + } else // variable name + singlevar(ls, checkname(ls), v, 0); + var_or_func_tail(ls, v); } -static void var_or_func_tail (LexState *ls, vardesc *v) { - for (;;) { - switch (ls->token) { - case '.': /* var_or_func_tail -> '.' NAME */ - next(ls); - lua_pushvar(ls, v); /* 'v' must be on stack */ - v->k = VDOT; - v->info = string_constant(ls->fs, checkname(ls)); - break; - - case '[': /* var_or_func_tail -> '[' exp1 ']' */ - next(ls); - lua_pushvar(ls, v); /* 'v' must be on stack */ - exp1(ls); - check(ls, ']'); - v->k = VINDEXED; - break; - - case ':': /* var_or_func_tail -> ':' NAME funcparams */ - next(ls); - lua_pushvar(ls, v); /* 'v' must be on stack */ - code_oparg(ls, PUSHSELF, 8, string_constant(ls->fs, checkname(ls)), 1); - v->k = VEXP; - v->info = funcparams(ls, 1); - break; - - case '(': case STRING: case '{': /* var_or_func_tail -> funcparams */ - lua_pushvar(ls, v); /* 'v' must be on stack */ - v->k = VEXP; - v->info = funcparams(ls, 0); - break; - - default: return; /* should be follow... */ - } - } +static void var_or_func_tail(LexState *ls, vardesc *v) { + for (;;) { + switch (ls->token) { + case '.': // var_or_func_tail -> '.' NAME + next(ls); + lua_pushvar(ls, v); // 'v' must be on stack + v->k = VDOT; + v->info = string_constant(ls->fs, checkname(ls)); + break; + case '[': // var_or_func_tail -> '[' exp1 ']' + next(ls); + lua_pushvar(ls, v); // 'v' must be on stack + exp1(ls); + check(ls, ']'); + v->k = VINDEXED; + break; + case ':': // var_or_func_tail -> ':' NAME funcparams + next(ls); + lua_pushvar(ls, v); // 'v' must be on stack + code_oparg(ls, PUSHSELF, 8, string_constant(ls->fs, checkname(ls)), 1); + v->k = VEXP; + v->info = funcparams(ls, 1); + break; + case '(': + case STRING: + case '{': // var_or_func_tail -> funcparams + lua_pushvar(ls, v); // 'v' must be on stack + v->k = VEXP; + v->info = funcparams(ls, 0); + break; + default: + return; // should be follow... + } + } } -static int32 funcparams (LexState *ls, int32 slf) { - FuncState *fs = ls->fs; - int32 nparams = 1; /* default value */ - switch (ls->token) { - case '(': { /* funcparams -> '(' explist ')' */ - listdesc e; - next(ls); - explist(ls, &e); - check(ls, ')'); - close_exp(ls, e.pc, 1); - nparams = e.n; - break; - } +static int32 funcparams(LexState *ls, int32 slf) { + FuncState *fs = ls->fs; + int32 nparams = 1; // default value + switch (ls->token) { + case '(': + { // funcparams -> '(' explist ')' + listdesc e; + next(ls); + explist(ls, &e); + check(ls, ')'); + close_exp(ls, e.pc, 1); + nparams = e.n; + break; + } + case '{': // funcparams -> constructor + constructor(ls); + break; + case STRING: // funcparams -> STRING + code_string(ls, ls->seminfo.ts); + next(ls); + break; + default: + luaX_error(ls, "function arguments expected"); + break; + } + code_byte(fs, 0); // save space for opcode + code_byte(fs, 0); // and nresult + code_byte(fs, nparams + slf); - case '{': /* funcparams -> constructor */ - constructor(ls); - break; - - case STRING: /* funcparams -> STRING */ - code_string(ls, ls->seminfo.ts); - next(ls); - break; - - default: - luaX_error(ls, "function arguments expected"); - break; - } - code_byte(fs, 0); /* save space for opcode */ - code_byte(fs, 0); /* and nresult */ - code_byte(fs, nparams+slf); - return fs->pc-1; + return fs->pc - 1; } -static void explist (LexState *ls, listdesc *d) { - switch (ls->token) { - case ELSE: case ELSEIF: case END: case UNTIL: - case EOS: case ';': case ')': - d->pc = 0; - d->n = 0; - break; - - default: - explist1(ls, d); - } +static void explist(LexState *ls, listdesc *d) { + switch (ls->token) { + case ELSE: + case ELSEIF: + case END: + case UNTIL: + case EOS: + case ';': + case ')': + d->pc = 0; + d->n = 0; + break; + default: + explist1(ls, d); + } } -static void explist1 (LexState *ls, listdesc *d) { - vardesc v; - exp0(ls, &v); - d->n = 1; - while (ls->token == ',') { - d->n++; - lua_pushvar(ls, &v); - next(ls); - exp0(ls, &v); - } - if (v.k == VEXP) - d->pc = v.info; - else { - lua_pushvar(ls, &v); - d->pc = 0; - } +static void explist1(LexState *ls, listdesc *d) { + vardesc v; + exp0(ls, &v); + d->n = 1; + while (ls->token == ',') { + d->n++; + lua_pushvar(ls, &v); + next(ls); + exp0(ls, &v); + } + if (v.k == VEXP) + d->pc = v.info; + else { + lua_pushvar(ls, &v); + d->pc = 0; + } } static void parlist (LexState *ls) { - int32 nparams = 0; - int32 dots = 0; - switch (ls->token) { - case DOTS: /* parlist -> DOTS */ - next(ls); - dots = 1; - break; - - case NAME: /* parlist, tailparlist -> NAME [',' tailparlist] */ - init: - store_localvar(ls, checkname(ls), nparams++); - if (ls->token == ',') { - next(ls); - switch (ls->token) { - case DOTS: /* tailparlist -> DOTS */ - next(ls); - dots = 1; - break; - - case NAME: /* tailparlist -> NAME [',' tailparlist] */ - goto init; - - default: luaX_error(ls, "NAME or `...' expected"); - } - } - break; - - case ')': break; /* parlist -> empty */ - - default: luaX_error(ls, "NAME or `...' expected"); - } - code_args(ls, nparams, dots); + int32 nparams = 0; + int32 dots = 0; + switch (ls->token) { + case DOTS: // parlist -> DOTS + next(ls); + dots = 1; + break; + case NAME: // parlist, tailparlist -> NAME [',' tailparlist] +init: + store_localvar(ls, checkname(ls), nparams++); + if (ls->token == ',') { + next(ls); + switch (ls->token) { + case DOTS: // tailparlist -> DOTS + next(ls); + dots = 1; + break; + case NAME: // tailparlist -> NAME [',' tailparlist] + goto init; + default: luaX_error(ls, "NAME or `...' expected"); + } + } + break; + case ')': + break; // parlist -> empty + default: + luaX_error(ls, "NAME or `...' expected"); + } + code_args(ls, nparams, dots); } static int32 localnamelist (LexState *ls) { - /* localnamelist -> NAME {',' NAME} */ - int32 i = 1; - store_localvar(ls, checkname(ls), 0); - while (ls->token == ',') { - next(ls); - store_localvar(ls, checkname(ls), i++); - } - return i; + // localnamelist -> NAME {',' NAME} + int32 i = 1; + store_localvar(ls, checkname(ls), 0); + while (ls->token == ',') { + next(ls); + store_localvar(ls, checkname(ls), i++); + } + return i; } static void decinit (LexState *ls, listdesc *d) { - /* decinit -> ['=' explist1] */ - if (ls->token == '=') { - next(ls); - explist1(ls, d); - } - else { - d->n = 0; - d->pc = 0; - } + // decinit -> ['=' explist1] + if (ls->token == '=') { + next(ls); + explist1(ls, d); + } else { + d->n = 0; + d->pc = 0; + } } static int32 assignment (LexState *ls, vardesc *v, int32 nvars) { - int32 left = 0; - /* dotted variables must be stored like regular indexed vars */ - if (v->k == VDOT) { - code_constant(ls, v->info); - v->k = VINDEXED; - } - if (ls->token == ',') { /* assignment -> ',' NAME assignment */ - vardesc nv; - next(ls); - var_or_func(ls, &nv); - if (nv.k == VEXP) - luaX_error(ls, "syntax error"); - left = assignment(ls, &nv, nvars+1); - } - else { /* assignment -> '=' explist1 */ - listdesc d; - check(ls, '='); - explist1(ls, &d); - adjust_mult_assign(ls, nvars, &d); - } - if (v->k != VINDEXED || left+(nvars-1) == 0) { - /* global/local var or indexed var without values in between */ - storevar(ls, v); - } - else { /* indexed var with values in between*/ - code_oparg(ls, SETTABLE, 0, left+(nvars-1), -1); - left += 2; /* table/index are not popped, because they aren't on top */ - } - return left; + int32 left = 0; + // dotted variables must be stored like regular indexed vars + if (v->k == VDOT) { + code_constant(ls, v->info); + v->k = VINDEXED; + } + if (ls->token == ',') { // assignment -> ',' NAME assignment + vardesc nv; + next(ls); + var_or_func(ls, &nv); + if (nv.k == VEXP) + luaX_error(ls, "syntax error"); + left = assignment(ls, &nv, nvars + 1); + } else { // assignment -> '=' explist1 + listdesc d; + check(ls, '='); + explist1(ls, &d); + adjust_mult_assign(ls, nvars, &d); + } + if (v->k != VINDEXED || left+(nvars-1) == 0) { + // global/local var or indexed var without values in between + storevar(ls, v); + } else { // indexed var with values in between + code_oparg(ls, SETTABLE, 0, left+(nvars-1), -1); + left += 2; // table/index are not popped, because they aren't on top + } + return left; } -static void constructor (LexState *ls) { - /* constructor -> '{' part [';' part] '}' */ - int32 line = ls->linenumber; - int32 pc = SaveWord(ls); - int32 nelems; - constdesc cd; - deltastack(ls, 1); - check(ls, '{'); - part(ls, &cd); - nelems = cd.n; - if (ls->token == ';') { - constdesc other_cd; - next(ls); - part(ls, &other_cd); - if (cd.k == other_cd.k) /* repeated parts? */ - luaX_error(ls, "invalid constructor syntax"); - nelems += other_cd.n; - } - check_match(ls, '}', '{', line); - fix_opcode(ls, pc, CREATEARRAY, 2, nelems); +static void constructor(LexState *ls) { + // constructor -> '{' part [';' part] '}' + int32 line = ls->linenumber; + int32 pc = SaveWord(ls); + int32 nelems; + constdesc cd; + deltastack(ls, 1); + check(ls, '{'); + part(ls, &cd); + nelems = cd.n; + if (ls->token == ';') { + constdesc other_cd; + next(ls); + part(ls, &other_cd); + if (cd.k == other_cd.k) // repeated parts? + luaX_error(ls, "invalid constructor syntax"); + nelems += other_cd.n; + } + check_match(ls, '}', '{', line); + fix_opcode(ls, pc, CREATEARRAY, 2, nelems); } -static void part (LexState *ls, constdesc *cd) { - switch (ls->token) { - case ';': case '}': /* part -> empty */ - cd->n = 0; - cd->k = ls->token; - return; +static void part(LexState *ls, constdesc *cd) { + switch (ls->token) { + case ';': + case '}': // part -> empty + cd->n = 0; + cd->k = ls->token; + return; + case NAME: + { + vardesc v; + exp0(ls, &v); + if (ls->token == '=') { + switch (v.k) { + case VGLOBAL: + code_constant(ls, v.info); + break; + case VLOCAL: + code_string(ls, ls->fs->localvar[v.info]); + break; + default: + luaX_error(ls, "`=' unexpected"); + } + next(ls); + exp1(ls); + cd->n = recfields(ls); + cd->k = 1; // record + } else { + lua_pushvar(ls, &v); + cd->n = listfields(ls); + cd->k = 0; // list + } + break; + } - case NAME: { - vardesc v; - exp0(ls, &v); - if (ls->token == '=') { - switch (v.k) { - case VGLOBAL: - code_constant(ls, v.info); - break; - case VLOCAL: - code_string(ls, ls->fs->localvar[v.info]); - break; - default: - luaX_error(ls, "`=' unexpected"); - } - next(ls); - exp1(ls); - cd->n = recfields(ls); - cd->k = 1; /* record */ - } - else { - lua_pushvar(ls, &v); - cd->n = listfields(ls); - cd->k = 0; /* list */ - } - break; - } - - case '[': /* part -> recfield recfields */ - recfield(ls); - cd->n = recfields(ls); - cd->k = 1; /* record */ - break; - - default: /* part -> exp1 listfields */ - exp1(ls); - cd->n = listfields(ls); - cd->k = 0; /* list */ - break; - } + case '[': // part -> recfield recfields + recfield(ls); + cd->n = recfields(ls); + cd->k = 1; // record + break; + default: // part -> exp1 listfields + exp1(ls); + cd->n = listfields(ls); + cd->k = 0; // list + break; + } } -static int32 recfields (LexState *ls) { - /* recfields -> { ',' recfield } [','] */ - int32 n = 1; /* one has been read before */ - while (ls->token == ',') { - next(ls); - if (ls->token == ';' || ls->token == '}') - break; - recfield(ls); - n++; - if (n%RFIELDS_PER_FLUSH == 0) - flush_record(ls, RFIELDS_PER_FLUSH); - } - flush_record(ls, n%RFIELDS_PER_FLUSH); - return n; +static int32 recfields(LexState *ls) { + // recfields -> { ',' recfield } [','] + int32 n = 1; // one has been read before + while (ls->token == ',') { + next(ls); + if (ls->token == ';' || ls->token == '}') + break; + recfield(ls); + n++; + if (n % RFIELDS_PER_FLUSH == 0) + flush_record(ls, RFIELDS_PER_FLUSH); + } + flush_record(ls, n % RFIELDS_PER_FLUSH); + return n; } -static int32 listfields (LexState *ls) { - /* listfields -> { ',' exp1 } [','] */ - int32 n = 1; /* one has been read before */ - while (ls->token == ',') { - next(ls); - if (ls->token == ';' || ls->token == '}') - break; - exp1(ls); - n++; - if (n%LFIELDS_PER_FLUSH == 0) - flush_list(ls, n/LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); - } - flush_list(ls, n/LFIELDS_PER_FLUSH, n%LFIELDS_PER_FLUSH); - return n; +static int32 listfields(LexState *ls) { + // listfields -> { ',' exp1 } [','] + int32 n = 1; // one has been read before + while (ls->token == ',') { + next(ls); + if (ls->token == ';' || ls->token == '}') + break; + exp1(ls); + n++; + if (n % LFIELDS_PER_FLUSH == 0) + flush_list(ls, n / LFIELDS_PER_FLUSH - 1, LFIELDS_PER_FLUSH); + } + flush_list(ls, n / LFIELDS_PER_FLUSH, n % LFIELDS_PER_FLUSH); + return n; } -static void recfield (LexState *ls) { - /* recfield -> (NAME | '['exp1']') = exp1 */ - switch (ls->token) { - case NAME: - code_string(ls, checkname(ls)); - break; - - case '[': - next(ls); - exp1(ls); - check(ls, ']'); - break; - - default: luaX_error(ls, "NAME or `[' expected"); - } - check(ls, '='); - exp1(ls); +static void recfield(LexState *ls) { + // recfield -> (NAME | '['exp1']') = exp1 + switch (ls->token) { + case NAME: + code_string(ls, checkname(ls)); + break; + case '[': + next(ls); + exp1(ls); + check(ls, ']'); + break; + default: + luaX_error(ls, "NAME or `[' expected"); + } + check(ls, '='); + exp1(ls); } - diff --git a/engine/lua/lparser.h b/engine/lua/lparser.h index 31b89244125..f48bc6054a1 100644 --- a/engine/lua/lparser.h +++ b/engine/lua/lparser.h @@ -10,11 +10,9 @@ #include "lobject.h" #include "lzio.h" - -void luaY_codedebugline (int32 line); -TProtoFunc *luaY_parser (ZIO *z); -void luaY_error (char *s); -void luaY_syntaxerror (char *s, char *token); - +void luaY_codedebugline(int32 line); +TProtoFunc *luaY_parser(ZIO *z); +void luaY_error(char *s); +void luaY_syntaxerror(char *s, char *token); #endif diff --git a/engine/lua/lrestore.cpp b/engine/lua/lrestore.cpp index 422858e26e3..1e6085dd6a5 100644 --- a/engine/lua/lrestore.cpp +++ b/engine/lua/lrestore.cpp @@ -1,13 +1,13 @@ -#include "ltask.h" -#include "lauxlib.h" -#include "lmem.h" -#include "ldo.h" -#include "ltm.h" -#include "ltable.h" -#include "lvm.h" -#include "lopcodes.h" -#include "lstring.h" -#include "lua.h" +#include "engine/lua/ltask.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lmem.h" +#include "engine/lua/ldo.h" +#include "engine/lua/ltm.h" +#include "engine/lua/ltable.h" +#include "engine/lua/lvm.h" +#include "engine/lua/lopcodes.h" +#include "engine/lua/lstring.h" +#include "engine/lua/lua.h" #include "common/endian.h" @@ -366,7 +366,7 @@ void lua_Restore(RestoreStream restoreStream, RestoreSint32 restoreSint32, Resto } int32 codeSize = restoreSint32(); - tempProtoFunc->code = (lua_Byte *)luaM_malloc(codeSize); + tempProtoFunc->code = (byte *)luaM_malloc(codeSize); restoreStream(tempProtoFunc->code, codeSize); arraysObj->object = tempProtoFunc; arraysObj++; diff --git a/engine/lua/lsave.cpp b/engine/lua/lsave.cpp index 577c94b039a..efd773abc82 100644 --- a/engine/lua/lsave.cpp +++ b/engine/lua/lsave.cpp @@ -1,13 +1,13 @@ -#include "ltask.h" -#include "lauxlib.h" -#include "lmem.h" -#include "ldo.h" -#include "ltm.h" -#include "ltable.h" -#include "lvm.h" -#include "lopcodes.h" -#include "lstring.h" -#include "lua.h" +#include "engine/lua/ltask.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lmem.h" +#include "engine/lua/ldo.h" +#include "engine/lua/ltm.h" +#include "engine/lua/ltable.h" +#include "engine/lua/lvm.h" +#include "engine/lua/lopcodes.h" +#include "engine/lua/lstring.h" +#include "engine/lua/lua.h" #include "common/endian.h" @@ -307,8 +307,8 @@ void lua_Save(SaveStream saveStream, SaveSint32 saveSint32, SaveUint32 saveUint3 saveSint32(tempProtoFunc->locvars[i].line); } - Byte *codePtr = tempProtoFunc->code + 2; - Byte *tmpPtr = codePtr; + byte *codePtr = tempProtoFunc->code + 2; + byte *tmpPtr = codePtr; int32 opcodeId; do { opcodeId = *tmpPtr; diff --git a/engine/lua/lstate.cpp b/engine/lua/lstate.cpp index a06f963c946..2237f041dbc 100644 --- a/engine/lua/lstate.cpp +++ b/engine/lua/lstate.cpp @@ -5,19 +5,18 @@ */ -#include "lbuiltin.h" -#include "ldo.h" -#include "lauxlib.h" -#include "lfunc.h" -#include "lgc.h" -#include "llex.h" -#include "lmem.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltask.h" -#include "ltm.h" - +#include "engine/lua/lbuiltin.h" +#include "engine/lua/ldo.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lfunc.h" +#include "engine/lua/lgc.h" +#include "engine/lua/llex.h" +#include "engine/lua/lmem.h" +#include "engine/lua/lstate.h" +#include "engine/lua/lstring.h" +#include "engine/lua/ltable.h" +#include "engine/lua/ltask.h" +#include "engine/lua/ltm.h" lua_State *lua_state = NULL; @@ -26,139 +25,135 @@ int32 globalTaskSerialId; void stderrorim (void); static luaL_reg stdErrorRimFunc[] = { - {"stderrorim", stderrorim} + { "stderrorim", stderrorim } }; -static void lua_openthr (void) -{ - L->numCblocks = 0; - L->Cstack.base = 0; - L->Cstack.lua2C = 0; - L->Cstack.num = 0; - L->errorJmp = NULL; - L->Mbuffsize = 0; - L->Mbuffnext = 0; - L->Mbuffbase = NULL; - L->Mbuffer = NULL; - L->Tstate = RUN; +static void lua_openthr() { + L->numCblocks = 0; + L->Cstack.base = 0; + L->Cstack.lua2C = 0; + L->Cstack.num = 0; + L->errorJmp = NULL; + L->Mbuffsize = 0; + L->Mbuffnext = 0; + L->Mbuffbase = NULL; + L->Mbuffer = NULL; + L->Tstate = RUN; } -void lua_resetglobals(void) { - globalTaskSerialId = 1; - lua_openthr(); - L->rootproto.next = NULL; - L->rootproto.marked = 0; - L->rootcl.next = NULL; - L->rootcl.marked = 0; - L->rootglobal.next = NULL; - L->rootglobal.marked = 0; - L->roottable.next = NULL; - L->roottable.marked = 0; - L->refArray = NULL; - L->refSize = 0; - L->GCthreshold = GARBAGE_BLOCK; - L->nblocks = 0; - L->root_task = luaM_new(struct lua_Task); - L->root_task->next = NULL; - L->last_task = L->root_task; - L->curr_task = L->root_task; - luaD_init(); - luaD_initthr(); - luaS_init(); - luaX_init(); +void lua_resetglobals() { + globalTaskSerialId = 1; + lua_openthr(); + L->rootproto.next = NULL; + L->rootproto.marked = 0; + L->rootcl.next = NULL; + L->rootcl.marked = 0; + L->rootglobal.next = NULL; + L->rootglobal.marked = 0; + L->roottable.next = NULL; + L->roottable.marked = 0; + L->refArray = NULL; + L->refSize = 0; + L->GCthreshold = GARBAGE_BLOCK; + L->nblocks = 0; + L->root_task = luaM_new(lua_Task); + L->root_task->next = NULL; + L->last_task = L->root_task; + L->curr_task = L->root_task; + luaD_init(); + luaD_initthr(); + luaS_init(); + luaX_init(); } -void lua_open (void) -{ - if (lua_state) return; - lua_state = luaM_new(lua_State); - lua_resetglobals(); - luaT_init(); - luaB_predefine(); - luaL_addlibtolist(stdErrorRimFunc, (sizeof(stdErrorRimFunc) / sizeof(stdErrorRimFunc[0]))); +void lua_open() { + if (lua_state) + return; + lua_state = luaM_new(lua_State); + lua_resetglobals(); + luaT_init(); + luaB_predefine(); + luaL_addlibtolist(stdErrorRimFunc, (sizeof(stdErrorRimFunc) / sizeof(stdErrorRimFunc[0]))); } -void lua_close (void) -{ - TaggedString *alludata = luaS_collectudata(); - L->GCthreshold = MAX_INT; /* to avoid GC during GC */ - luaC_hashcallIM((Hash *)L->roottable.next); /* GC t.methods for tables */ - luaC_strcallIM(alludata); /* GC tag methods for userdata */ - luaD_gcIM(&luaO_nilobject); /* GC tag method for nil (signal end of GC) */ - luaH_free((Hash *)L->roottable.next); - luaF_freeproto((TProtoFunc *)L->rootproto.next); - luaF_freeclosure((Closure *)L->rootcl.next); - luaS_free(alludata); - luaS_freeall(); - luaM_free(L->stack.stack); - luaM_free(L->IMtable); - luaM_free(L->refArray); - luaM_free(L->Mbuffer); - luaM_free(L); - L = NULL; -#ifdef DEBUG - printf("total de blocos: %ld\n", numblocks); - printf("total de memoria: %ld\n", totalmem); +void lua_close() { + TaggedString *alludata = luaS_collectudata(); + L->GCthreshold = MAX_INT; // to avoid GC during GC + luaC_hashcallIM((Hash *)L->roottable.next); // GC t.methods for tables + luaC_strcallIM(alludata); // GC tag methods for userdata + luaD_gcIM(&luaO_nilobject); // GC tag method for nil (signal end of GC) + luaH_free((Hash *)L->roottable.next); + luaF_freeproto((TProtoFunc *)L->rootproto.next); + luaF_freeclosure((Closure *)L->rootcl.next); + luaS_free(alludata); + luaS_freeall(); + luaM_free(L->stack.stack); + luaM_free(L->IMtable); + luaM_free(L->refArray); + luaM_free(L->Mbuffer); + luaM_free(L); + L = NULL; +#ifdef LUA_DEBUG + printf("total de blocos: %ld\n", numblocks); + printf("total de memoria: %ld\n", totalmem); #endif } - -lua_State *lua_setstate (lua_State *st) { - lua_State *old = lua_state; - lua_state = st; - return old; +lua_State *lua_setstate(lua_State *st) { + lua_State *old = lua_state; + lua_state = st; + return old; } - -static void savetask (struct lua_Task *t) { - t->stack = L->stack; - t->Cstack = L->Cstack; - t->errorJmp = L->errorJmp; - t->ci = L->ci; - t->base_ci = L->base_ci; - t->base_ci_size = L->base_ci_size; - t->end_ci = L->end_ci; - t->Mbuffer = L->Mbuffer; - t->Mbuffbase = L->Mbuffbase; - t->Mbuffsize = L->Mbuffsize; - t->Mbuffnext = L->Mbuffnext; - memcpy(t->Cblocks, L->Cblocks, sizeof(L->Cblocks)); - t->numCblocks = L->numCblocks; - t->Tstate = L->Tstate; +static void savetask(lua_Task *t) { + t->stack = L->stack; + t->Cstack = L->Cstack; + t->errorJmp = L->errorJmp; + t->ci = L->ci; + t->base_ci = L->base_ci; + t->base_ci_size = L->base_ci_size; + t->end_ci = L->end_ci; + t->Mbuffer = L->Mbuffer; + t->Mbuffbase = L->Mbuffbase; + t->Mbuffsize = L->Mbuffsize; + t->Mbuffnext = L->Mbuffnext; + memcpy(t->Cblocks, L->Cblocks, sizeof(L->Cblocks)); + t->numCblocks = L->numCblocks; + t->Tstate = L->Tstate; } -static void loadtask (struct lua_Task *t) { - L->stack = t->stack; - L->Cstack = t->Cstack; - L->errorJmp = t->errorJmp; - L->ci = t->ci; - L->base_ci = t->base_ci; - L->base_ci_size = t->base_ci_size; - L->end_ci = t->end_ci; - L->Mbuffer = t->Mbuffer; - L->Mbuffbase = t->Mbuffbase; - L->Mbuffsize = t->Mbuffsize; - L->Mbuffnext = t->Mbuffnext; - memcpy(L->Cblocks, t->Cblocks, sizeof(L->Cblocks)); - L->numCblocks = t->numCblocks; - L->Tstate = t->Tstate; +static void loadtask(struct lua_Task *t) { + L->stack = t->stack; + L->Cstack = t->Cstack; + L->errorJmp = t->errorJmp; + L->ci = t->ci; + L->base_ci = t->base_ci; + L->base_ci_size = t->base_ci_size; + L->end_ci = t->end_ci; + L->Mbuffer = t->Mbuffer; + L->Mbuffbase = t->Mbuffbase; + L->Mbuffsize = t->Mbuffsize; + L->Mbuffnext = t->Mbuffnext; + memcpy(L->Cblocks, t->Cblocks, sizeof(L->Cblocks)); + L->numCblocks = t->numCblocks; + L->Tstate = t->Tstate; } -void luaI_switchtask(struct lua_Task *t) { - savetask(L->curr_task); - L->curr_task = t; - loadtask(t); +void luaI_switchtask(lua_Task *t) { + savetask(L->curr_task); + L->curr_task = t; + loadtask(t); } -struct lua_Task *luaI_newtask (void) { - struct lua_Task *result; +struct lua_Task *luaI_newtask() { + struct lua_Task *result; - savetask(L->curr_task); - result = luaM_new(struct lua_Task); - L->curr_task = result; - result->next = NULL; - lua_openthr(); - luaD_initthr(); - result->id = globalTaskSerialId++; - return result; + savetask(L->curr_task); + result = luaM_new(lua_Task); + L->curr_task = result; + result->next = NULL; + lua_openthr(); + luaD_initthr(); + result->id = globalTaskSerialId++; + return result; } diff --git a/engine/lua/lstate.h b/engine/lua/lstate.h index 30cbfa8276b..22785ee1cb1 100644 --- a/engine/lua/lstate.h +++ b/engine/lua/lstate.h @@ -9,124 +9,117 @@ #include -#include "lobject.h" -#include "lua.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lua.h" #define MAX_C_BLOCKS 10 - #define GARBAGE_BLOCK 150 - typedef int32 StkId; /* index to stack elements */ struct Stack { - TObject *top; - TObject *stack; - TObject *last; + TObject *top; + TObject *stack; + TObject *last; }; struct C_Lua_Stack { - StkId base; /* when Lua calls C or C calls Lua, points to */ - /* the first slot after the last parameter. */ - StkId lua2C; /* points to first element of "array" lua2C */ - int32 num; /* size of "array" lua2C */ + StkId base; // when Lua calls C or C calls Lua, points to + // the first slot after the last parameter. + StkId lua2C; // points to first element of "array" lua2C + int32 num; // size of "array" lua2C }; typedef struct { - int32 size; - int32 nuse; /* number of elements (including EMPTYs) */ - TaggedString **hash; + int32 size; + int32 nuse; // number of elements (including EMPTYs) + TaggedString **hash; } stringtable; - -enum Status {LOCK, HOLD, FREE, COLLECTED}; +enum Status { LOCK, HOLD, FREE, COLLECTED }; struct ref { - TObject o; - enum Status status; + TObject o; + enum Status status; }; - struct CallInfo { - Closure *c; - TProtoFunc *tf; /* Set to NULL for C function */ - StkId base; - Byte *pc; - int32 nResults; + Closure *c; + TProtoFunc *tf; // Set to NULL for C function + StkId base; + byte *pc; + int32 nResults; }; - -enum TaskState {RUN, YIELD, PAUSE, DONE}; +enum TaskState { RUN, YIELD, PAUSE, DONE }; struct lua_Task { - struct Stack stack; - struct C_Lua_Stack Cstack; - jmp_buf *errorJmp; - struct CallInfo *ci; - struct CallInfo *base_ci; - int32 base_ci_size; - struct CallInfo *end_ci; - char *Mbuffer; - char *Mbuffbase; - int32 Mbuffsize; - int32 Mbuffnext; - struct C_Lua_Stack Cblocks[MAX_C_BLOCKS]; - int32 numCblocks; - enum TaskState Tstate; - struct lua_Task *next; - int32 id; + Stack stack; + C_Lua_Stack Cstack; + jmp_buf *errorJmp; + CallInfo *ci; + CallInfo *base_ci; + int32 base_ci_size; + CallInfo *end_ci; + char *Mbuffer; + char *Mbuffbase; + int32 Mbuffsize; + int32 Mbuffnext; + C_Lua_Stack Cblocks[MAX_C_BLOCKS]; + int32 numCblocks; + enum TaskState Tstate; + struct lua_Task *next; + int32 id; }; struct lua_State { - /* thread-specific state */ - struct Stack stack; /* Lua stack */ - struct C_Lua_Stack Cstack; /* C2lua struct */ - jmp_buf *errorJmp; /* current error recover point */ - struct CallInfo *ci; /* call info for current function */ - struct CallInfo *base_ci; /* array of CallInfo's */ - int32 base_ci_size; - struct CallInfo *end_ci; /* points after end of ci array */ - char *Mbuffer; /* global buffer */ - char *Mbuffbase; /* current first position of Mbuffer */ - int32 Mbuffsize; /* size of Mbuffer */ - int32 Mbuffnext; /* next position to fill in Mbuffer */ - struct C_Lua_Stack Cblocks[MAX_C_BLOCKS]; - int32 numCblocks; /* number of nested Cblocks */ - enum TaskState Tstate; /* state of current thread */ - /* global state */ - struct lua_Task *root_task; /* first task created */ - struct lua_Task *curr_task; - struct lua_Task *last_task; - TObject errorim; /* error tag method */ - GCnode rootproto; /* list of all prototypes */ - GCnode rootcl; /* list of all closures */ - GCnode roottable; /* list of all tables */ - GCnode rootglobal; /* list of strings with global values */ - stringtable *string_root; /* array of hash tables for strings and udata */ - struct IM *IMtable; /* table for tag methods */ - int32 IMtable_size; /* size of IMtable */ - int32 last_tag; /* last used tag in IMtable */ - struct ref *refArray; /* locked objects */ - int32 refSize; /* size of refArray */ - int32 GCthreshold; - int32 nblocks; /* number of 'blocks' currently allocated */ + // thread-specific state + Stack stack; // Lua stack + C_Lua_Stack Cstack; // C2lua struct + jmp_buf *errorJmp; // current error recover point + CallInfo *ci; // call info for current function + CallInfo *base_ci; // array of CallInfo's + int32 base_ci_size; + CallInfo *end_ci; // points after end of ci array + char *Mbuffer; // global buffer + char *Mbuffbase; // current first position of Mbuffer + int32 Mbuffsize; // size of Mbuffer + int32 Mbuffnext; // next position to fill in Mbuffer + C_Lua_Stack Cblocks[MAX_C_BLOCKS]; + int32 numCblocks; // number of nested Cblocks + enum TaskState Tstate; // state of current thread + // global state + lua_Task *root_task; // first task created + lua_Task *curr_task; + lua_Task *last_task; + TObject errorim; // error tag method + GCnode rootproto; // list of all prototypes + GCnode rootcl; // list of all closures + GCnode roottable; // list of all tables + GCnode rootglobal; // list of strings with global values + stringtable *string_root; // array of hash tables for strings and udata + struct IM *IMtable; // table for tag methods + int32 IMtable_size; // size of IMtable + int32 last_tag; // last used tag in IMtable + ref *refArray; // locked objects + int32 refSize; // size of refArray + int32 GCthreshold; + int32 nblocks; // number of 'blocks' currently allocated }; - extern lua_State *lua_state; - extern int32 globalTaskSerialId; #define L lua_state -void lua_resetglobals(void); +void lua_resetglobals(); -/* Switch to the given task */ -void luaI_switchtask(struct lua_Task *t); +// Switch to the given task */ +void luaI_switchtask(lua_Task *t); -/* Create a new task and switch to it */ -struct lua_Task *luaI_newtask(void); +// Create a new task and switch to it +lua_Task *luaI_newtask(); #endif diff --git a/engine/lua/lstring.cpp b/engine/lua/lstring.cpp index a8fa41ef5b3..788aa1803e7 100644 --- a/engine/lua/lstring.cpp +++ b/engine/lua/lstring.cpp @@ -5,305 +5,270 @@ */ -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "lstring.h" -#include "lua.h" +#include "engine/lua/lmem.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lstate.h" +#include "engine/lua/lstring.h" +#include "engine/lua/lua.h" +#define gcsizestring(l) (1 + (l / 64)) // "weight" for a string with length 'l' +TaggedString EMPTY = {{NULL, 2}, 0L, 0, {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; -#define gcsizestring(l) (1+(l/64)) /* "weight" for a string with length 'l' */ - - - -TaggedString EMPTY = {{NULL, 2}, 0L, 0, - {{{LUA_T_NIL, {NULL}}, 0L}}, {0}}; - - -void luaS_init (void) -{ - int32 i; - L->string_root = luaM_newvector(NUM_HASHS, stringtable); - for (i=0; istring_root[i].size = 0; - L->string_root[i].nuse = 0; - L->string_root[i].hash = NULL; - } +void luaS_init() { + int32 i; + L->string_root = luaM_newvector(NUM_HASHS, stringtable); + for (i = 0; i < NUM_HASHS; i++) { + L->string_root[i].size = 0; + L->string_root[i].nuse = 0; + L->string_root[i].hash = NULL; + } } - -static uint32 hash_s (const char *s, int32 l) -{ - uint32 h = 0; - while (l--) - h = ((h<<5)-h)^(byte)*(s++); - return h; +static uint32 hash_s(const char *s, int32 l) { + uint32 h = 0; + while (l--) + h = ((h << 5) - h) ^ (byte) * (s++); + return h; } -static int32 newsize (stringtable *tb) -{ - int32 size = tb->size; - int32 realuse = 0; - int32 i; - /* count how many entries are really in use */ - for (i=0; ihash[i] != NULL && tb->hash[i] != &EMPTY) - realuse++; - if (2*(realuse+1) <= size) /* +1 is the new element */ - return size; /* don't need to grow, just rehash to clear EMPTYs */ - else - return luaO_redimension(size); +static int32 newsize(stringtable *tb) { + int32 size = tb->size; + int32 realuse = 0; + int32 i; + + // count how many entries are really in use + for (i = 0; i < size; i++) + if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) + realuse++; + if (2 * (realuse + 1) <= size) // +1 is the new element + return size; // don't need to grow, just rehash to clear EMPTYs + else + return luaO_redimension(size); } +static void grow(stringtable *tb) { + int32 ns = newsize(tb); + TaggedString **newhash = luaM_newvector(ns, TaggedString *); + int32 i; -static void grow (stringtable *tb) -{ - - int32 ns = newsize(tb); - TaggedString **newhash = luaM_newvector(ns, TaggedString *); - int32 i; - for (i=0; inuse = 0; - for (i=0; isize; i++) { - if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { - int32 h = tb->hash[i]->hash%ns; - while (newhash[h]) - h = (h+1)%ns; - newhash[h] = tb->hash[i]; - tb->nuse++; - } - } - luaM_free(tb->hash); - tb->size = ns; - tb->hash = newhash; + for (i = 0; i < ns; i++) + newhash[i] = NULL; + // rehash + tb->nuse = 0; + for (i = 0; i < tb->size; i++) { + if (tb->hash[i] != NULL && tb->hash[i] != &EMPTY) { + int32 h = tb->hash[i]->hash % ns; + while (newhash[h]) + h = (h + 1) % ns; + newhash[h] = tb->hash[i]; + tb->nuse++; + } + } + luaM_free(tb->hash); + tb->size = ns; + tb->hash = newhash; } - -static TaggedString *newone_s (const char *str, int32 l, uint32 h) -{ - TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString)+l); - memcpy(ts->str, str, l); - ts->str[l] = 0; /* ending 0 */ - ts->u.s.globalval.ttype = LUA_T_NIL; /* initialize global value */ - ts->u.s.len = l; - ts->constindex = 0; - L->nblocks += gcsizestring(l); - ts->head.marked = 0; - ts->head.next = (GCnode *)ts; /* signal it is in no list */ - ts->hash = h; - return ts; +static TaggedString *newone_s(const char *str, int32 l, uint32 h) { + TaggedString *ts = (TaggedString *)luaM_malloc(sizeof(TaggedString) + l); + memcpy(ts->str, str, l); + ts->str[l] = 0; // ending 0 + ts->u.s.globalval.ttype = LUA_T_NIL; // initialize global value + ts->u.s.len = l; + ts->constindex = 0; + L->nblocks += gcsizestring(l); + ts->head.marked = 0; + ts->head.next = (GCnode *)ts; // signal it is in no list + ts->hash = h; + return ts; } -static TaggedString *newone_u (char *buff, int32 tag, uint32 h) -{ - TaggedString *ts = luaM_new(TaggedString); - ts->u.d.v = buff; - ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; - ts->constindex = -1; /* tag -> this is a userdata */ - L->nblocks++; - ts->head.marked = 0; - ts->head.next = (GCnode *)ts; /* signal it is in no list */ - ts->hash = h; - return ts; +static TaggedString *newone_u(char *buff, int32 tag, uint32 h) { + TaggedString *ts = luaM_new(TaggedString); + ts->u.d.v = buff; + ts->u.d.tag = (tag == LUA_ANYTAG) ? 0 : tag; + ts->constindex = -1; // tag -> this is a userdata + L->nblocks++; + ts->head.marked = 0; + ts->head.next = (GCnode *)ts; // signal it is in no list + ts->hash = h; + return ts; } -static TaggedString *insert_s (const char *str, int32 l, stringtable *tb) -{ - TaggedString *ts; - uint32 h = hash_s(str, l); - int32 size = tb->size; - int32 i; - int32 j = -1; - if ((int32)tb->nuse*3 >= size*2) { - grow(tb); - size = tb->size; - } - for (i = h%size; (ts = tb->hash[i]) != NULL; ) { - if (ts == &EMPTY) - j = i; - else if (ts->constindex >= 0 && - ts->u.s.len == l && - (memcmp(str, ts->str, l) == 0)) return ts; - if (++i == size) i=0; - } - /* not found */ - if (j != -1) /* is there an EMPTY space? */ - i = j; - else - tb->nuse++; - ts = tb->hash[i] = newone_s(str, l, h); - return ts; +static TaggedString *insert_s (const char *str, int32 l, stringtable *tb) { + TaggedString *ts; + uint32 h = hash_s(str, l); + int32 size = tb->size; + int32 i; + int32 j = -1; + if ((int32)tb->nuse * 3 >= size * 2) { + grow(tb); + size = tb->size; + } + for (i = h % size; (ts = tb->hash[i]); ) { + if (ts == &EMPTY) + j = i; + else if (ts->constindex >= 0 && ts->u.s.len == l && (memcmp(str, ts->str, l) == 0)) + return ts; + if (++i == size) + i = 0; + } + // not found + if (j != -1) // is there an EMPTY space? + i = j; + else + tb->nuse++; + ts = tb->hash[i] = newone_s(str, l, h); + return ts; } -static TaggedString *insert_u (void *buff, int32 tag, stringtable *tb) -{ - TaggedString *ts; - unsigned long h = (unsigned long)buff; - int32 size = tb->size; - int32 i; - int32 j = -1; - if (tb->nuse*3 >= size*2) { - grow(tb); - size = tb->size; - } - for (i = h%size; (ts = tb->hash[i]) != NULL; ) { - if (ts == &EMPTY) - j = i; - else if (ts->constindex < 0 && /* is a udata? */ - (tag == ts->u.d.tag || tag == LUA_ANYTAG) && - buff == ts->u.d.v) - return ts; - if (++i == size) i=0; - } - /* not found */ - if (j != -1) /* is there an EMPTY space? */ - i = j; - else - tb->nuse++; - ts = tb->hash[i] = newone_u((char*)buff, tag, h); - return ts; +static TaggedString *insert_u(void *buff, int32 tag, stringtable *tb) { + TaggedString *ts; + unsigned long h = (unsigned long)buff; + int32 size = tb->size; + int32 i; + int32 j = -1; + if (tb->nuse * 3 >= size * 2) { + grow(tb); + size = tb->size; + } + for (i = h % size; (ts = tb->hash[i]) != NULL; ) { + if (ts == &EMPTY) + j = i; + else if (ts->constindex < 0 && (tag == ts->u.d.tag || tag == LUA_ANYTAG) && buff == ts->u.d.v) + return ts; + if (++i == size) + i = 0; + } + // not found + if (j != -1) // is there an EMPTY space? + i = j; + else + tb->nuse++; + ts = tb->hash[i] = newone_u((char*)buff, tag, h); + return ts; } -TaggedString *luaS_createudata (void *udata, int32 tag) -{ - return insert_u(udata, tag, &L->string_root[(unsigned long)udata%NUM_HASHS]); +TaggedString *luaS_createudata(void *udata, int32 tag) { + return insert_u(udata, tag, &L->string_root[(unsigned long)udata % NUM_HASHS]); } -TaggedString *luaS_newlstr (const char *str, int32 l) -{ - int32 i = (l==0)?0:(byte)str[0]; - return insert_s(str, l, &L->string_root[i%NUM_HASHS]); +TaggedString *luaS_newlstr(const char *str, int32 l) { + int32 i = (l == 0) ? 0 : (byte)str[0]; + return insert_s(str, l, &L->string_root[i % NUM_HASHS]); } -TaggedString *luaS_new (const char *str) -{ - return luaS_newlstr(str, strlen(str)); +TaggedString *luaS_new(const char *str) { + return luaS_newlstr(str, strlen(str)); } -TaggedString *luaS_newfixedstring (const char *str) -{ - TaggedString *ts = luaS_new(str); - if (ts->head.marked == 0) - ts->head.marked = 2; /* avoid GC */ - return ts; +TaggedString *luaS_newfixedstring(const char *str) { + TaggedString *ts = luaS_new(str); + if (ts->head.marked == 0) + ts->head.marked = 2; // avoid GC + return ts; } - -void luaS_free (TaggedString *l) -{ - while (l) { - TaggedString *next = (TaggedString *)l->head.next; - L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); - luaM_free(l); - l = next; - } +void luaS_free(TaggedString *l) { + while (l) { + TaggedString *next = (TaggedString *)l->head.next; + L->nblocks -= (l->constindex == -1) ? 1 : gcsizestring(l->u.s.len); + luaM_free(l); + l = next; + } } - /* ** Garbage collection functions. */ -static void remove_from_list (GCnode *l) -{ - while (l) { - GCnode *next = l->next; - while (next && !next->marked) - next = l->next = next->next; - l = next; - } +static void remove_from_list(GCnode *l) { + while (l) { + GCnode *next = l->next; + while (next && !next->marked) + next = l->next = next->next; + l = next; + } } - -TaggedString *luaS_collector (void) -{ - TaggedString *frees = NULL; - int32 i; - remove_from_list(&(L->rootglobal)); - for (i=0; istring_root[i]; - int32 j; - for (j=0; jsize; j++) { - TaggedString *t = tb->hash[j]; - if (t == NULL) continue; - if (t->head.marked == 1) - t->head.marked = 0; - else if (!t->head.marked) { - t->head.next = (GCnode *)frees; - frees = t; - tb->hash[j] = &EMPTY; - } - } - } - return frees; +TaggedString *luaS_collector() { + TaggedString *frees = NULL; + int32 i; + remove_from_list(&(L->rootglobal)); + for (i = 0; i < NUM_HASHS; i++) { + stringtable *tb = &L->string_root[i]; + int32 j; + for (j = 0; j < tb->size; j++) { + TaggedString *t = tb->hash[j]; + if (!t) + continue; + if (t->head.marked == 1) + t->head.marked = 0; + else if (!t->head.marked) { + t->head.next = (GCnode *)frees; + frees = t; + tb->hash[j] = &EMPTY; + } + } + } + return frees; } - -TaggedString *luaS_collectudata (void) -{ - TaggedString *frees = NULL; - int32 i; - L->rootglobal.next = NULL; /* empty list of globals */ - for (i=0; istring_root[i]; - int32 j; - for (j=0; jsize; j++) { - TaggedString *t = tb->hash[j]; - if (t == NULL || t == &EMPTY || t->constindex != -1) - continue; /* get only user data */ - t->head.next = (GCnode *)frees; - frees = t; - tb->hash[j] = &EMPTY; - } - } - return frees; +TaggedString *luaS_collectudata() { + TaggedString *frees = NULL; + int32 i; + L->rootglobal.next = NULL; // empty list of globals + for (i = 0; i < NUM_HASHS; i++) { + stringtable *tb = &L->string_root[i]; + int32 j; + for (j = 0; j < tb->size; j++) { + TaggedString *t = tb->hash[j]; + if (!t || t == &EMPTY || t->constindex != -1) + continue; // get only user data + t->head.next = (GCnode *)frees; + frees = t; + tb->hash[j] = &EMPTY; + } + } + return frees; } - -void luaS_freeall (void) -{ - int32 i; - for (i=0; istring_root[i]; - int32 j; - for (j=0; jsize; j++) { - TaggedString *t = tb->hash[j]; - if (t == &EMPTY) continue; - luaM_free(t); - } - luaM_free(tb->hash); - } - luaM_free(L->string_root); +void luaS_freeall() { + int32 i; + for (i = 0; i < NUM_HASHS; i++) { + stringtable *tb = &L->string_root[i]; + int32 j; + for (j = 0; j < tb->size; j++) { + TaggedString *t = tb->hash[j]; + if (t == &EMPTY) + continue; + luaM_free(t); + } + luaM_free(tb->hash); + } + luaM_free(L->string_root); } - -void luaS_rawsetglobal (TaggedString *ts, TObject *newval) -{ - ts->u.s.globalval = *newval; - if (ts->head.next == (GCnode *)ts) { /* is not in list? */ - ts->head.next = L->rootglobal.next; - L->rootglobal.next = (GCnode *)ts; - } +void luaS_rawsetglobal(TaggedString *ts, TObject *newval) { + ts->u.s.globalval = *newval; + if (ts->head.next == (GCnode *)ts) { // is not in list? + ts->head.next = L->rootglobal.next; + L->rootglobal.next = (GCnode *)ts; + } } - -char *luaS_travsymbol (int32 (*fn)(TObject *)) -{ - TaggedString *g; - for (g=(TaggedString *)L->rootglobal.next; g; g=(TaggedString *)g->head.next) - if (fn(&g->u.s.globalval)) - return g->str; - return NULL; +char *luaS_travsymbol (int32 (*fn)(TObject *)) { + TaggedString *g; + for (g = (TaggedString *)L->rootglobal.next; g; g = (TaggedString *)g->head.next) + if (fn(&g->u.s.globalval)) + return g->str; + return NULL; } - -int32 luaS_globaldefined (const char *name) -{ - TaggedString *ts = luaS_new(name); - return ts->u.s.globalval.ttype != LUA_T_NIL; +int32 luaS_globaldefined(const char *name) { + TaggedString *ts = luaS_new(name); + return ts->u.s.globalval.ttype != LUA_T_NIL; } diff --git a/engine/lua/ltable.cpp b/engine/lua/ltable.cpp index 5865dc74584..52a1b651cba 100644 --- a/engine/lua/ltable.cpp +++ b/engine/lua/ltable.cpp @@ -4,214 +4,191 @@ ** See Copyright Notice in lua.h */ -#include "lauxlib.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "ltable.h" -#include "lua.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lmem.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lstate.h" +#include "engine/lua/ltable.h" +#include "engine/lua/lua.h" - -#define gcsize(n) (1+(n/16)) - -#define nuse(t) ((t)->nuse) +#define gcsize(n) (1 + (n / 16)) +#define nuse(t) ((t)->nuse) #define nodevector(t) ((t)->node) +#define REHASH_LIMIT 0.70 // avoid more than this % full +#define TagDefault LUA_T_ARRAY; - -#define REHASH_LIMIT 0.70 /* avoid more than this % full */ - -#define TagDefault LUA_T_ARRAY; - - - -static long int hashindex (TObject *ref) -{ - long int h; - switch (ttype(ref)) { - case LUA_T_NUMBER: - h = (long int)nvalue(ref); - break; - case LUA_T_STRING: case LUA_T_USERDATA: - h = (IntPoint)tsvalue(ref); - break; - case LUA_T_ARRAY: - h = (IntPoint)avalue(ref); - break; - case LUA_T_PROTO: - h = (IntPoint)tfvalue(ref); - break; - case LUA_T_CPROTO: - h = (IntPoint)fvalue(ref); - break; - case LUA_T_CLOSURE: - h = (IntPoint)clvalue(ref); - break; - case LUA_T_TASK: - h = (long int)nvalue(ref); - break; - default: - lua_error("unexpected type to index table"); - h = 0; /* to avoid warnings */ - } - return (h >= 0 ? h : -(h+1)); +static long int hashindex(TObject *ref) { + long int h; + switch (ttype(ref)) { + case LUA_T_NUMBER: + h = (long int)nvalue(ref); + break; + case LUA_T_STRING: + case LUA_T_USERDATA: + h = (long int)tsvalue(ref); + break; + case LUA_T_ARRAY: + h = (long int)avalue(ref); + break; + case LUA_T_PROTO: + h = (long int)tfvalue(ref); + break; + case LUA_T_CPROTO: + h = (long int)fvalue(ref); + break; + case LUA_T_CLOSURE: + h = (long int)clvalue(ref); + break; + case LUA_T_TASK: + h = (long int)nvalue(ref); + break; + default: + lua_error("unexpected type to index table"); + h = 0; // to avoid warnings + } + return (h >= 0 ? h : -(h + 1)); } - -int32 present (Hash *t, TObject *key) -{ - int32 tsize = nhash(t); - long int h = hashindex(key); - int32 h1 = h%tsize; - TObject *rf = ref(node(t, h1)); - if (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)) { - int32 h2 = h%(tsize-2) + 1; - do { - h1 += h2; - if (h1 >= tsize) h1 -= tsize; - rf = ref(node(t, h1)); - } while (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)); - } - return h1; +int32 present(Hash *t, TObject *key) { + int32 tsize = nhash(t); + long int h = hashindex(key); + int32 h1 = h % tsize; + TObject *rf = ref(node(t, h1)); + if (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)) { + int32 h2 = h % (tsize - 2) + 1; + do { + h1 += h2; + if (h1 >= tsize) + h1 -= tsize; + rf = ref(node(t, h1)); + } while (ttype(rf) != LUA_T_NIL && !luaO_equalObj(key, rf)); + } + return h1; } - /* ** Alloc a vector node */ -Node *hashnodecreate (int32 nhash) -{ - Node *v = luaM_newvector(nhash, Node); - int32 i; - for (i=0; ihead.next; - L->nblocks -= gcsize(frees->nhash); - hashdelete(frees); - frees = next; - } +void luaH_free(Hash *frees) { + while (frees) { + Hash *next = (Hash *)frees->head.next; + L->nblocks -= gcsize(frees->nhash); + hashdelete(frees); + frees = next; + } } - -Hash *luaH_new (int32 nhash) -{ - Hash *t = luaM_new(Hash); - nhash = luaO_redimension((int32)((float)nhash/REHASH_LIMIT)); - nodevector(t) = hashnodecreate(nhash); - nhash(t) = nhash; - nuse(t) = 0; - t->htag = TagDefault; - luaO_insertlist(&(L->roottable), (GCnode *)t); - L->nblocks += gcsize(nhash); - return t; +Hash *luaH_new(int32 nhash) { + Hash *t = luaM_new(Hash); + nhash = luaO_redimension((int32)((float)nhash / REHASH_LIMIT)); + nodevector(t) = hashnodecreate(nhash); + nhash(t) = nhash; + nuse(t) = 0; + t->htag = TagDefault; + luaO_insertlist(&(L->roottable), (GCnode *)t); + L->nblocks += gcsize(nhash); + return t; } - -static int32 newsize (Hash *t) -{ - Node *v = t->node; - int32 size = nhash(t); - int32 realuse = 0; - int32 i; - for (i=0; inode; + int32 size = nhash(t); + int32 realuse = 0; + int32 i; + for (i = 0; i < size; i++) { + if (ttype(ref(v + i)) != LUA_T_NIL && ttype(val(v + i)) != LUA_T_NIL) + realuse++; + } + if (2 * (realuse + 1) <= size) // +1 is the new element + return size; // don't need to grow, just rehash + else + return luaO_redimension(size); } -static void rehash (Hash *t) -{ - int32 nold = nhash(t); - Node *vold = nodevector(t); - int32 nnew = newsize(t); - int32 i; - nodevector(t) = hashnodecreate(nnew); - nhash(t) = nnew; - for (i=0; inblocks += gcsize(nnew)-gcsize(nold); - luaM_free(vold); +static void rehash(Hash *t) { + int32 nold = nhash(t); + Node *vold = nodevector(t); + int32 nnew = newsize(t); + int32 i; + nodevector(t) = hashnodecreate(nnew); + nhash(t) = nnew; + for (i = 0; i < nold; i++) { + Node *n = vold + i; + if (ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL) + *node(t, present(t, ref(n))) = *n; // copy old node to luaM_new hash + } + L->nblocks += gcsize(nnew) - gcsize(nold); + luaM_free(vold); } /* ** If the hash node is present, return its pointer, otherwise return ** null. */ -TObject *luaH_get (Hash *t, TObject *ref) -{ - int32 h = present(t, ref); - if (ttype(ref(node(t, h))) != LUA_T_NIL) return val(node(t, h)); - else return NULL; +TObject *luaH_get(Hash *t, TObject *ref) { + int32 h = present(t, ref); + if (ttype(ref(node(t, h))) != LUA_T_NIL) + return val(node(t, h)); + else + return NULL; } - /* ** If the hash node is present, return its pointer, otherwise create a luaM_new ** node for the given reference and also return its pointer. */ -TObject *luaH_set (Hash *t, TObject *ref) -{ - Node *n = node(t, present(t, ref)); - if (ttype(ref(n)) == LUA_T_NIL) { - nuse(t)++; - if ((float)nuse(t) > (float)nhash(t)*REHASH_LIMIT) { - rehash(t); - n = node(t, present(t, ref)); - } - *ref(n) = *ref; - ttype(val(n)) = LUA_T_NIL; - } - return (val(n)); +TObject *luaH_set(Hash *t, TObject *ref) { + Node *n = node(t, present(t, ref)); + if (ttype(ref(n)) == LUA_T_NIL) { + nuse(t)++; + if ((float)nuse(t) > (float)nhash(t) * REHASH_LIMIT) { + rehash(t); + n = node(t, present(t, ref)); + } + *ref(n) = *ref; + ttype(val(n)) = LUA_T_NIL; + } + return (val(n)); } - -static Node *hashnext (Hash *t, int32 i) -{ - Node *n; - int32 tsize = nhash(t); - if (i >= tsize) - return NULL; - n = node(t, i); - while (ttype(ref(n)) == LUA_T_NIL || ttype(val(n)) == LUA_T_NIL) { - if (++i >= tsize) - return NULL; - n = node(t, i); - } - return node(t, i); +static Node *hashnext(Hash *t, int32 i) { + Node *n; + int32 tsize = nhash(t); + if (i >= tsize) + return NULL; + n = node(t, i); + while (ttype(ref(n)) == LUA_T_NIL || ttype(val(n)) == LUA_T_NIL) { + if (++i >= tsize) + return NULL; + n = node(t, i); + } + return node(t, i); } -Node *luaH_next (TObject *o, TObject *r) -{ - Hash *t = avalue(o); - if (ttype(r) == LUA_T_NIL) - return hashnext(t, 0); - else { - int32 i = present(t, r); - Node *n = node(t, i); - luaL_arg_check(ttype(ref(n))!=LUA_T_NIL && ttype(val(n))!=LUA_T_NIL, - 2, "key not found"); - return hashnext(t, i+1); - } +Node *luaH_next(TObject *o, TObject *r) { + Hash *t = avalue(o); + if (ttype(r) == LUA_T_NIL) + return hashnext(t, 0); + else { + int32 i = present(t, r); + Node *n = node(t, i); + luaL_arg_check(ttype(ref(n)) != LUA_T_NIL && ttype(val(n)) != LUA_T_NIL, 2, "key not found"); + return hashnext(t, i + 1); + } } diff --git a/engine/lua/ltable.h b/engine/lua/ltable.h index b986c949095..aadef3c84a1 100644 --- a/engine/lua/ltable.h +++ b/engine/lua/ltable.h @@ -7,20 +7,19 @@ #ifndef ltable_h #define ltable_h -#include "lobject.h" +#include "engine/lua/lobject.h" - -#define node(t,i) (&(t)->node[i]) +#define node(t, i) (&(t)->node[i]) #define ref(n) (&(n)->ref) #define val(n) (&(n)->val) #define nhash(t) ((t)->nhash) -Hash *luaH_new (int32 nhash); -void luaH_free (Hash *frees); -TObject *luaH_get (Hash *t, TObject *ref); -TObject *luaH_set (Hash *t, TObject *ref); -Node *luaH_next (TObject *o, TObject *r); -Node *hashnodecreate (int32 nhash); -int32 present (Hash *t, TObject *key); +Hash *luaH_new(int32 nhash); +void luaH_free(Hash *frees); +TObject *luaH_get(Hash *t, TObject *ref); +TObject *luaH_set(Hash *t, TObject *ref); +Node *luaH_next(TObject *o, TObject *r); +Node *hashnodecreate(int32 nhash); +int32 present(Hash *t, TObject *key); #endif diff --git a/engine/lua/ltask.cpp b/engine/lua/ltask.cpp index 42a916959df..596a5ef517a 100644 --- a/engine/lua/ltask.cpp +++ b/engine/lua/ltask.cpp @@ -5,25 +5,25 @@ #include "ldo.h" #include "lvm.h" -void pause_scripts (void) { - struct lua_Task *t; +void pause_scripts() { + lua_Task *t; for (t = L->root_task->next; t != NULL; t = t->next) { - if ((L->curr_task != t) && (t->Tstate != DONE)) + if (L->curr_task != t && t->Tstate != DONE) t->Tstate = PAUSE; } } -void unpause_scripts (void) { - struct lua_Task *t; +void unpause_scripts() { + lua_Task *t; for (t = L->root_task->next; t != NULL; t = t->next) { - if ((L->curr_task != t) && (t->Tstate != DONE)) + if (L->curr_task != t && t->Tstate != DONE) t->Tstate = YIELD; } } -void start_script (void) { +void start_script() { struct lua_Task *old_task = L->curr_task, *new_task; TObject *f = L->stack.stack + L->Cstack.lua2C; @@ -38,44 +38,44 @@ void start_script (void) { if (ttype(f) != LUA_T_PROTO) lua_error("can only start_script with a Lua function"); - /* Create a new task with an empty stack */ + // Create a new task with an empty stack new_task = luaI_newtask(); - /* Put the function and arguments onto the new task's stack */ + // Put the function and arguments onto the new task's stack for (int32 i = 0; i < old_task->Cstack.num; i++) { *(L->stack.top) = *(old_task->stack.stack + old_task->Cstack.lua2C + i); incr_top; } - /* Create a CallInfo frame */ + // Create a CallInfo frame luaD_precall(L->stack.stack, 1, MULT_RET); ttype(L->stack.stack) = (ttype(L->stack.stack) == LUA_T_CLOSURE) ? LUA_T_CLMARK : LUA_T_PMARK; - /* Switch back to the old task */ + // Switch back to the old task L->Tstate = YIELD; luaI_switchtask(old_task); L->curr_task = old_task; - /* Insert new task at end of list */ + // Insert new task at end of list L->last_task->next = new_task; L->last_task = new_task; - /* Return task handle */ + // Return task handle ttype(L->stack.top) = LUA_T_TASK; nvalue(L->stack.top) = (real)new_task->id; incr_top; } -void stop_script (void) { - struct lua_Task *prev, *t; +void stop_script() { + lua_Task *prev, *t; TObject *f = L->stack.stack + L->Cstack.lua2C; int32 match = 0; - if ((f == LUA_NOOBJECT) || (ttype(f) != LUA_T_CLOSURE && ttype(f) != LUA_T_PROTO && ttype(f) != LUA_T_TASK)) + if (f == LUA_NOOBJECT || (ttype(f) != LUA_T_CLOSURE && ttype(f) != LUA_T_PROTO && ttype(f) != LUA_T_TASK)) lua_error("Bad argument to stop_script"); prev = L->root_task; - while ((t = prev->next) != NULL) { + while ((t = prev->next)) { switch (ttype(f)) { case LUA_T_CLOSURE: match = (ttype(t->stack.stack) == LUA_T_CLMARK && clvalue(t->stack.stack) == clvalue(f)); @@ -86,14 +86,14 @@ void stop_script (void) { case LUA_T_TASK: match = (t->id == (int32)nvalue(f)); break; - default: /* Shut up gcc */ + default: // Shut up gcc break; } if (match) { - prev->next = t->next; /* Remove from list of active tasks */ + prev->next = t->next; // Remove from list of active tasks t->next = NULL; - if (prev->next == NULL) { + if (!prev->next) { L->last_task = prev; if (t == L->curr_task) { L->Tstate = DONE; @@ -107,8 +107,8 @@ void stop_script (void) { } } -void next_script (void) { - struct lua_Task *t = NULL, *prev; +void next_script() { + lua_Task *t = NULL, *prev; TObject *f = L->stack.stack + L->Cstack.lua2C; if (f == LUA_NOOBJECT) @@ -126,11 +126,11 @@ void next_script (void) { } else { lua_error("Bad argument to next_script."); } - if (t == NULL) { + if (!t) { lua_pushnil(); } else { t = t->next; - if (t == NULL) { + if (!t) { lua_pushnil(); } else { ttype(L->stack.top) = LUA_T_TASK; @@ -140,11 +140,11 @@ void next_script (void) { } } -void identify_script (void) { - struct lua_Task *t; +void identify_script() { + lua_Task *t; TObject *f = L->stack.stack + L->Cstack.lua2C; - if ((f == LUA_NOOBJECT) || ttype(f) != LUA_T_TASK) { + if (f == LUA_NOOBJECT || ttype(f) != LUA_T_TASK) { lua_error("Bad argument to identify_script"); } @@ -154,16 +154,16 @@ void identify_script (void) { break; } - if ((t == NULL) || (t->Tstate == DONE)) { - ttype(L->stack.top) = LUA_T_NIL; + if (!t || t->Tstate == DONE) { + ttype(L->stack.top) = LUA_T_NIL; } else { *L->stack.top = *t->stack.stack; } incr_top; } -void find_script (void) { - struct lua_Task *t = NULL, *foundTask = NULL; +void find_script() { + lua_Task *t = NULL, *foundTask = NULL; TObject *f = L->stack.stack + L->Cstack.lua2C; int32 countTasks = 0, taskId; @@ -202,7 +202,7 @@ void find_script (void) { lua_error("Bad argument to find_script"); } - if (t != NULL) { + if (t) { ttype(L->stack.top) = LUA_T_TASK; nvalue(L->stack.top) = (real)t->id; incr_top; @@ -213,13 +213,13 @@ void find_script (void) { } } -void break_here (void) { - struct CallInfo *ci; +void break_here() { + CallInfo *ci; if (L->curr_task == L->root_task) { lua_error("Cannot break in root thread"); } - /* Check for any C functions in the call stack */ + // Check for any C functions in the call stack for (ci = L->ci-1; ci > L->base_ci; ci--) if (ci->tf == NULL) lua_error("Cannot yield through C function"); @@ -227,7 +227,7 @@ void break_here (void) { L->Tstate = YIELD; } -void current_script (void) { +void current_script() { if (L->curr_task == L->root_task) { lua_pushnil(); } else { @@ -237,13 +237,13 @@ void current_script (void) { } } -void lua_runtasks (void) { - struct lua_Task *t, *prev; - struct lua_Task *old_task = L->curr_task; +void lua_runtasks() { + lua_Task *t, *prev; + lua_Task *old_task = L->curr_task; jmp_buf myErrorJmp; prev = L->root_task; - while ((t = prev->next) != NULL) { + while ((t = prev->next)) { luaI_switchtask(t); // Tstate is not available until after switching tasks if (t->Tstate == PAUSE) { @@ -254,10 +254,10 @@ void lua_runtasks (void) { L->Tstate = RUN; if (setjmp(myErrorJmp) == 0) { luaV_execute(L->base_ci + 1); - if (L->Tstate == RUN) { /* Must have run to completion */ + if (L->Tstate == RUN) { // Must have run to completion L->Tstate = DONE; } - } else { /* an error occurred */ + } else { // an error occurred L->Tstate = DONE; } L->errorJmp = NULL; @@ -269,13 +269,13 @@ void lua_runtasks (void) { // execution gets hosed. Test Case: Switching between tw.set and // tb.set in Rubacava causes a crash without this. prev = L->root_task; - while ((t = prev->next) != NULL) { + while ((t = prev->next)) { luaI_switchtask(t); if (L->Tstate == DONE) { // Remove from list of active tasks luaI_switchtask(old_task); prev->next = t->next; t->next = NULL; - if (prev->next == NULL) { + if (!prev->next) { L->last_task = prev; } luaM_free(t); diff --git a/engine/lua/ltask.h b/engine/lua/ltask.h index 730343f6f87..fc28eb7437a 100644 --- a/engine/lua/ltask.h +++ b/engine/lua/ltask.h @@ -1,20 +1,18 @@ #ifndef ltask_h #define ltask_h -#include "lua.h" -#include "lstate.h" +#include "engine/lua/lua.h" +#include "engine/lua/lstate.h" extern int32 task_tag; -void start_script (void); -void stop_script (void); -void next_script (void); -void identify_script (void); -void pause_scripts (void); -void unpause_scripts (void); -void find_script (void); -void break_here (void); - -void gc_task (void); +void start_script(); +void stop_script(); +void next_script(); +void identify_script(); +void pause_scripts(); +void unpause_scripts(); +void find_script(); +void break_here(); #endif diff --git a/engine/lua/ltm.cpp b/engine/lua/ltm.cpp index 2741352eb96..b9b2e2181f1 100644 --- a/engine/lua/ltm.cpp +++ b/engine/lua/ltm.cpp @@ -5,257 +5,227 @@ */ -#include "lauxlib.h" -#include "lmem.h" -#include "lobject.h" -#include "lstate.h" -#include "ltm.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/lmem.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lstate.h" +#include "engine/lua/ltm.h" -const char *luaT_eventname[] = { /* ORDER IM */ - "gettable", "settable", "index", "getglobal", "setglobal", "add", - "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge", - "concat", "gc", "function", NULL +const char *luaT_eventname[] = { // ORDER IM + "gettable", "settable", "index", "getglobal", "setglobal", "add", + "sub", "mul", "div", "pow", "unm", "lt", "le", "gt", "ge", + "concat", "gc", "function", NULL }; - -static int32 luaI_checkevent (const char *name, const char *list[]) -{ - int32 e = luaL_findstring(name, list); - if (e < 0) - luaL_verror("`%.50s' is not a valid event name", name); - return e; +static int32 luaI_checkevent(const char *name, const char *list[]) { + int32 e = luaL_findstring(name, list); + if (e < 0) + luaL_verror("`%.50s' is not a valid event name", name); + return e; } - - /* events in LUA_T_NIL are all allowed, since this is used as a -* 'placeholder' for "default" fallbacks -*/ -static char validevents[NUM_TAGS][IM_N] = { /* ORDER LUA_T, ORDER IM */ -{1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, /* LUA_T_USERDATA */ -{1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_NUMBER */ -{1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, /* LUA_T_STRING */ -{0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_ARRAY */ -{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_PROTO */ -{1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, /* LUA_T_CPROTO */ -{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, /* LUA_T_TASK */ -{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} /* LUA_T_NIL */ + * 'placeholder' for "default" fallbacks + */ +static char validevents[NUM_TAGS][IM_N] = { // ORDER LUA_T, ORDER IM + {1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1}, // LUA_T_USERDATA + {1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1}, // LUA_T_NUMBER + {1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, // LUA_T_STRING + {0, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // LUA_T_ARRAY + {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, // LUA_T_PROTO + {1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0}, // LUA_T_CPROTO + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}, // LUA_T_TASK + {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1} // LUA_T_NIL }; - -static int32 validevent (int32 t, int32 e) -{ /* ORDER LUA_T */ - return (t < LUA_T_NIL) ? 1 : validevents[-t][e]; +static int32 validevent(int32 t, int32 e) { // ORDER LUA_T + return (t < LUA_T_NIL) ? 1 : validevents[-t][e]; } - -static void init_entry (int32 tag) -{ - int32 i; - for (i=0; iIMtable_size = NUM_TAGS*2; - L->last_tag = -(NUM_TAGS-1); - L->IMtable = luaM_newvector(L->IMtable_size, struct IM); - for (t=-(L->IMtable_size-1); t<=0; t++) - init_entry(t); +void luaT_init() { + int32 t; + L->IMtable_size = NUM_TAGS * 2; + L->last_tag = -(NUM_TAGS - 1); + L->IMtable = luaM_newvector(L->IMtable_size, struct IM); + for (t = -(L->IMtable_size - 1); t <= 0; t++) + init_entry(t); } - -int32 lua_newtag (void) -{ - --L->last_tag; - if ((-L->last_tag) >= L->IMtable_size) - L->IMtable_size = luaM_growvector(&L->IMtable, L->IMtable_size, - struct IM, memEM, MAX_INT); - init_entry(L->last_tag); - return L->last_tag; +int32 lua_newtag() { + --L->last_tag; + if (-L->last_tag >= L->IMtable_size) + L->IMtable_size = luaM_growvector(&L->IMtable, L->IMtable_size, struct IM, memEM, MAX_INT); + init_entry(L->last_tag); + return L->last_tag; } - -static void checktag (int32 tag) -{ - if (!(L->last_tag <= tag && tag <= 0)) - luaL_verror("%d is not a valid tag", tag); +static void checktag(int32 tag) { + if (!(L->last_tag <= tag && tag <= 0)) + luaL_verror("%d is not a valid tag", tag); } -void luaT_realtag (int32 tag) -{ - if (!(L->last_tag <= tag && tag < LUA_T_NIL)) - luaL_verror("tag %d is not result of `newtag'", tag); +void luaT_realtag(int32 tag) { + if (!(L->last_tag <= tag && tag < LUA_T_NIL)) + luaL_verror("tag %d is not result of `newtag'", tag); } - -int32 lua_copytagmethods (int32 tagto, int32 tagfrom) -{ - int32 e; - checktag(tagto); - checktag(tagfrom); - for (e=0; evalue.a->htag; - case LUA_T_USERDATA: { - int32 tag = o->value.ts->u.d.tag; - return (tag >= 0) ? LUA_T_USERDATA : tag; - } - case LUA_T_CLOSURE: - return o->value.cl->consts[0].ttype; -#ifdef DEBUG - case LUA_T_PMARK: case LUA_T_CMARK: - case LUA_T_CLMARK: case LUA_T_LINE: - LUA_INTERNALERROR("invalid type"); +int32 luaT_efectivetag(TObject *o) { + int32 t; + switch (t = ttype(o)) { + case LUA_T_ARRAY: + return o->value.a->htag; + case LUA_T_USERDATA: + { + int32 tag = o->value.ts->u.d.tag; + return (tag >= 0) ? LUA_T_USERDATA : tag; + } + case LUA_T_CLOSURE: + return o->value.cl->consts[0].ttype; +#ifdef LUA_DEBUG + case LUA_T_PMARK: + case LUA_T_CMARK: + case LUA_T_CLMARK: + case LUA_T_LINE: + LUA_INTERNALERROR("invalid type"); #endif - default: - return t; - } + default: + return t; + } } - -TObject *luaT_gettagmethod (int32 t, const char *event) -{ - int32 e = luaI_checkevent(event, luaT_eventname); - checktag(t); - if (validevent(t, e)) - return luaT_getim(t,e); - else - return &luaO_nilobject; +TObject *luaT_gettagmethod(int32 t, const char *event) { + int32 e = luaI_checkevent(event, luaT_eventname); + checktag(t); + if (validevent(t, e)) + return luaT_getim(t,e); + else + return &luaO_nilobject; } - -void luaT_settagmethod (int32 t, const char *event, TObject *func) -{ - TObject temp = *func; - int32 e = luaI_checkevent(event, luaT_eventname); - checktag(t); - if (!validevent(t, e)) - luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d", - luaT_eventname[e], t); - *func = *luaT_getim(t,e); - *luaT_getim(t, e) = temp; +void luaT_settagmethod(int32 t, const char *event, TObject *func) { + TObject temp = *func; + int32 e = luaI_checkevent(event, luaT_eventname); + checktag(t); + if (!validevent(t, e)) + luaL_verror("settagmethod: cannot change tag method `%.20s' for tag %d", + luaT_eventname[e], t); + *func = *luaT_getim(t,e); + *luaT_getim(t, e) = temp; } - -const char *luaT_travtagmethods (int32 (*fn)(TObject *)) -{ - int32 e; - if (fn(&L->errorim)) - return "error"; - for (e=IM_GETTABLE; e<=IM_FUNCTION; e++) { /* ORDER IM */ - int32 t; - for (t=0; t>=L->last_tag; t--) - if (fn(luaT_getim(t,e))) - return luaT_eventname[e]; - } - return NULL; +const char *luaT_travtagmethods(int32 (*fn)(TObject *)) { + int32 e; + if (fn(&L->errorim)) + return "error"; + for (e = IM_GETTABLE; e <= IM_FUNCTION; e++) { // ORDER IM + int32 t; + for (t = 0; t >= L->last_tag; t--) + if (fn(luaT_getim(t, e))) + return luaT_eventname[e]; + } + return NULL; } - /* -* =================================================================== * compatibility with old fallback system */ #ifdef LUA_COMPAT2_5 #include "lapi.h" -void errorFB (void) -{ - lua_Object o = lua_getparam(1); - if (lua_isstring(o)) - fprintf(stderr, "lua: %s\n", lua_getstring(o)); - else - fprintf(stderr, "lua: unknown error\n"); +void errorFB() { + lua_Object o = lua_getparam(1); + if (lua_isstring(o)) + fprintf(stderr, "lua: %s\n", lua_getstring(o)); + else + fprintf(stderr, "lua: unknown error\n"); } +void nilFB() { } -void nilFB (void) { } - - -void typeFB (void) -{ - lua_error("unexpected type"); +void typeFB () { + lua_error("unexpected type"); } - -static void fillvalids (IMS e, TObject *func) -{ - int32 t; - for (t=LUA_T_NIL; t<=LUA_T_USERDATA; t++) - if (validevent(t, e)) - *luaT_getim(t, e) = *func; +static void fillvalids(IMS e, TObject *func) { + int32 t; + for (t = LUA_T_NIL; t <= LUA_T_USERDATA; t++) + if (validevent(t, e)) + *luaT_getim(t, e) = *func; } - -void luaT_setfallback (void) -{ - static const char *oldnames [] = {"error", "getglobal", "arith", "order", NULL}; - TObject oldfunc; - lua_CFunction replace; - const char *name = luaL_check_string(1); - lua_Object func = lua_getparam(2); - luaL_arg_check(lua_isfunction(func), 2, "function expected"); - switch (luaL_findstring(name, oldnames)) { - case 0: /* old error fallback */ - oldfunc = L->errorim; - L->errorim = *luaA_Address(func); - replace = errorFB; - break; - case 1: /* old getglobal fallback */ - oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); - *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); - replace = nilFB; - break; - case 2: { /* old arith fallback */ - int32 i; - oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); - for (i=IM_ADD; i<=IM_UNM; i++) /* ORDER IM */ - fillvalids(i, luaA_Address(func)); - replace = typeFB; - break; - } - case 3: { /* old order fallback */ - int32 i; - oldfunc = *luaT_getim(LUA_T_NIL, IM_LT); - for (i=IM_LT; i<=IM_GE; i++) /* ORDER IM */ - fillvalids(i, luaA_Address(func)); - replace = typeFB; - break; - } - default: { - int32 e; - if ((e = luaL_findstring(name, luaT_eventname)) >= 0) { - oldfunc = *luaT_getim(LUA_T_NIL, e); - fillvalids(e, luaA_Address(func)); - replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; - } - else { - luaL_verror("`%.50s' is not a valid fallback name", name); - replace = NULL; /* to avoid warnings */ - } - } - } - if (oldfunc.ttype != LUA_T_NIL) - luaA_pushobject(&oldfunc); - else - lua_pushcfunction(replace); +void luaT_setfallback() { + static const char *oldnames [] = { "error", "getglobal", "arith", "order", NULL }; + TObject oldfunc; + lua_CFunction replace; + const char *name = luaL_check_string(1); + lua_Object func = lua_getparam(2); + luaL_arg_check(lua_isfunction(func), 2, "function expected"); + switch (luaL_findstring(name, oldnames)) { + case 0: // old error fallback + oldfunc = L->errorim; + L->errorim = *luaA_Address(func); + replace = errorFB; + break; + case 1: // old getglobal fallback + oldfunc = *luaT_getim(LUA_T_NIL, IM_GETGLOBAL); + *luaT_getim(LUA_T_NIL, IM_GETGLOBAL) = *luaA_Address(func); + replace = nilFB; + break; + case 2: + { // old arith fallback + int32 i; + oldfunc = *luaT_getim(LUA_T_NUMBER, IM_POW); + for (i = IM_ADD; i <= IM_UNM; i++) // ORDER IM + fillvalids(i, luaA_Address(func)); + replace = typeFB; + break; + } + case 3: + { // old order fallback + int32 i; + oldfunc = *luaT_getim(LUA_T_NIL, IM_LT); + for (i = IM_LT; i <= IM_GE; i++) // ORDER IM + fillvalids(i, luaA_Address(func)); + replace = typeFB; + break; + } + default: + { + int32 e; + if ((e = luaL_findstring(name, luaT_eventname)) >= 0) { + oldfunc = *luaT_getim(LUA_T_NIL, e); + fillvalids(e, luaA_Address(func)); + replace = (e == IM_GC || e == IM_INDEX) ? nilFB : typeFB; + } else { + luaL_verror("`%.50s' is not a valid fallback name", name); + replace = NULL; // to avoid warnings + } + } + } + if (oldfunc.ttype != LUA_T_NIL) + luaA_pushobject(&oldfunc); + else + lua_pushcfunction(replace); } + #endif diff --git a/engine/lua/ltm.h b/engine/lua/ltm.h index e9cd11b50dd..0a2216e3959 100644 --- a/engine/lua/ltm.h +++ b/engine/lua/ltm.h @@ -8,56 +8,54 @@ #define ltm_h -#include "lobject.h" -#include "lstate.h" +#include "engine/lua/lobject.h" +#include "engine/lua/lstate.h" /* * WARNING: if you change the order of this enumeration, * grep "ORDER IM" */ typedef enum { - IM_GETTABLE = 0, - IM_SETTABLE, - IM_INDEX, - IM_GETGLOBAL, - IM_SETGLOBAL, - IM_ADD, - IM_SUB, - IM_MUL, - IM_DIV, - IM_POW, - IM_UNM, - IM_LT, - IM_LE, - IM_GT, - IM_GE, - IM_CONCAT, - IM_GC, - IM_FUNCTION + IM_GETTABLE = 0, + IM_SETTABLE, + IM_INDEX, + IM_GETGLOBAL, + IM_SETGLOBAL, + IM_ADD, + IM_SUB, + IM_MUL, + IM_DIV, + IM_POW, + IM_UNM, + IM_LT, + IM_LE, + IM_GT, + IM_GE, + IM_CONCAT, + IM_GC, + IM_FUNCTION } eIMS; typedef int32 IMS; #define IM_N 18 - struct IM { - TObject int_method[IM_N]; + TObject int_method[IM_N]; }; -#define luaT_getim(tag,event) (&L->IMtable[-(tag)].int_method[event]) -#define luaT_getimbyObj(o,e) (luaT_getim(luaT_efectivetag(o),(e))) +#define luaT_getim(tag, event) (&L->IMtable[-(tag)].int_method[event]) +#define luaT_getimbyObj(o, e) (luaT_getim(luaT_efectivetag(o), (e))) extern const char *luaT_eventname[]; +void luaT_init(); +void luaT_realtag(int32 tag); +int32 luaT_efectivetag(TObject *o); +void luaT_settagmethod(int32 t, const char *event, TObject *func); +TObject *luaT_gettagmethod(int32 t, const char *event); +const char *luaT_travtagmethods(int32 (*fn)(TObject *)); -void luaT_init (void); -void luaT_realtag (int32 tag); -int32 luaT_efectivetag (TObject *o); -void luaT_settagmethod (int32 t, const char *event, TObject *func); -TObject *luaT_gettagmethod (int32 t, const char *event); -const char *luaT_travtagmethods (int32 (*fn)(TObject *)); - -void luaT_setfallback (void); /* only if LUA_COMPAT2_5 */ +void luaT_setfallback(); // only if LUA_COMPAT2_5 #endif diff --git a/engine/lua/lua.h b/engine/lua/lua.h index d088d607528..cbedecaf984 100644 --- a/engine/lua/lua.h +++ b/engine/lua/lua.h @@ -12,7 +12,7 @@ #ifndef lua_h #define lua_h -#define LUA_VERSION "Lua 3.1" +#define LUA_VERSION "Lua 3.1" #define LUA_COPYRIGHT "Copyright (C) 1994-1998 TeCGraf, PUC-Rio" #define LUA_AUTHORS "W. Celes, R. Ierusalimschy & L. H. de Figueiredo" @@ -20,7 +20,7 @@ #define LUA_ANYTAG (-1) -typedef void (*lua_CFunction)(void); +typedef void (*lua_CFunction)(); typedef uint32 lua_Object; typedef struct lua_State lua_State; @@ -49,109 +49,103 @@ extern RestoreCallback restoreCallbackPtr; void lua_Save(SaveStream, SaveSint32, SaveUint32); void lua_Restore(RestoreStream, RestoreSint32, RestoreUint32); -void lua_removelibslists(void); +void lua_removelibslists(); -void lua_open (void); -void lua_close (void); -lua_State *lua_setstate (lua_State *st); +void lua_open(); +void lua_close(); +lua_State *lua_setstate(lua_State *st); -lua_Object lua_settagmethod (int32 tag, const char *event); /* In: new method */ -lua_Object lua_gettagmethod (int32 tag, const char *event); -lua_Object lua_seterrormethod (void); /* In: new method */ +lua_Object lua_settagmethod(int32 tag, const char *event); // In: new method +lua_Object lua_gettagmethod(int32 tag, const char *event); +lua_Object lua_seterrormethod(); // In: new method -int32 lua_newtag (void); -int32 lua_copytagmethods (int32 tagto, int32 tagfrom); -void lua_settag (int32 tag); /* In: object */ +int32 lua_newtag(); +int32 lua_copytagmethods(int32 tagto, int32 tagfrom); +void lua_settag(int32 tag); // In: object -void lua_error (const char *s); -int32 lua_dostring (const char *string); /* Out: returns */ -int32 lua_dobuffer (const char *buff, int32 size, const char *name); - /* Out: returns */ -int32 lua_callfunction (lua_Object f); - /* In: parameters; Out: returns */ +void lua_error(const char *s); +int32 lua_dostring(const char *string); // Out: returns +int32 lua_dobuffer(const char *buff, int32 size, const char *name); +// Out: returns +int32 lua_callfunction(lua_Object f); +// In: parameters; Out: returns */ -void lua_beginblock (void); -void lua_endblock (void); +void lua_beginblock(); +void lua_endblock(); -lua_Object lua_lua2C (int32 number); -#define lua_getparam(_) lua_lua2C(_) -#define lua_getresult(_) lua_lua2C(_) +lua_Object lua_lua2C(int32 number); -int32 lua_isnil (lua_Object object); -int32 lua_istable (lua_Object object); -int32 lua_isuserdata (lua_Object object); -int32 lua_iscfunction (lua_Object object); -int32 lua_isnumber (lua_Object object); -int32 lua_isstring (lua_Object object); -int32 lua_isfunction (lua_Object object); +#define lua_getparam(_) lua_lua2C(_) +#define lua_getresult(_) lua_lua2C(_) -double lua_getnumber (lua_Object object); -const char *lua_getstring (lua_Object object); -int32 lua_strlen (lua_Object object); -lua_CFunction lua_getcfunction (lua_Object object); -void *lua_getuserdata (lua_Object object); +int32 lua_isnil (lua_Object object); +int32 lua_istable (lua_Object object); +int32 lua_isuserdata (lua_Object object); +int32 lua_iscfunction (lua_Object object); +int32 lua_isnumber (lua_Object object); +int32 lua_isstring (lua_Object object); +int32 lua_isfunction (lua_Object object); +double lua_getnumber (lua_Object object); +const char *lua_getstring (lua_Object object); +int32 lua_strlen (lua_Object object); +lua_CFunction lua_getcfunction (lua_Object object); +void *lua_getuserdata (lua_Object object); -void lua_pushnil (void); -void lua_pushnumber (double n); -void lua_pushlstring (const char *s, int32 len); -void lua_pushstring (const char *s); -void lua_pushcclosure (lua_CFunction fn, int32 n); -void lua_pushusertag (void *u, int32 tag); -void lua_pushobject (lua_Object object); +void lua_pushnil(); +void lua_pushnumber(double n); +void lua_pushlstring(const char *s, int32 len); +void lua_pushstring(const char *s); +void lua_pushcclosure(lua_CFunction fn, int32 n); +void lua_pushusertag(void *u, int32 tag); +void lua_pushobject(lua_Object object); -lua_Object lua_pop (void); +lua_Object lua_pop(); +lua_Object lua_getglobal(const char *name); +lua_Object lua_rawgetglobal(const char *name); +void lua_setglobal(const char *name); // In: value +void lua_rawsetglobal(const char *name); // In: value -lua_Object lua_getglobal (const char *name); -lua_Object lua_rawgetglobal (const char *name); -void lua_setglobal (const char *name); /* In: value */ -void lua_rawsetglobal (const char *name); /* In: value */ +void lua_settable(); // In: table, index, value +void lua_rawsettable(); // In: table, index, value +lua_Object lua_gettable(); // In: table, index +lua_Object lua_rawgettable(); // In: table, index -void lua_settable (void); /* In: table, index, value */ -void lua_rawsettable (void); /* In: table, index, value */ -lua_Object lua_gettable (void); /* In: table, index */ -lua_Object lua_rawgettable (void); /* In: table, index */ +int32 lua_tag(lua_Object object); -int32 lua_tag (lua_Object object); +int32 lua_ref(int32 lock); // In: value +lua_Object lua_getref(int32 ref); +void lua_unref(int32 ref); +lua_Object lua_createtable(); +int32 lua_collectgarbage(int32 limit); -int32 lua_ref (int32 lock); /* In: value */ -lua_Object lua_getref (int32 ref); -void lua_unref (int32 ref); +void lua_runtasks(); +void current_script(); -lua_Object lua_createtable (void); - -int32 lua_collectgarbage (int32 limit); - -void lua_runtasks (void); - -void current_script (void); - -/* =============================================================== */ /* some useful macros/derived functions */ -int32 (lua_call) (char *name); +int32 (lua_call)(char *name); #define lua_call(name) lua_callfunction(lua_getglobal(name)) -void (lua_pushref) (int32 ref); +void (lua_pushref)(int32 ref); #define lua_pushref(ref) lua_pushobject(lua_getref(ref)) -int32 (lua_refobject) (lua_Object o, int32 l); +int32 (lua_refobject)(lua_Object o, int32 l); #define lua_refobject(o,l) (lua_pushobject(o), lua_ref(l)) -void (lua_register) (char *n, lua_CFunction f); -#define lua_register(n,f) (lua_pushcfunction(f), lua_setglobal(n)) +void (lua_register)(char *n, lua_CFunction f); +#define lua_register(n, f) (lua_pushcfunction(f), lua_setglobal(n)) -void (lua_pushuserdata) (void *u); -#define lua_pushuserdata(u) lua_pushusertag(u, 0) +void (lua_pushuserdata)(void *u); +#define lua_pushuserdata(u) lua_pushusertag(u, 0) -void (lua_pushcfunction) (lua_CFunction f); +void (lua_pushcfunction)(lua_CFunction f); #define lua_pushcfunction(f) lua_pushcclosure(f, 0) -int32 (lua_clonetag) (int32 t); +int32 (lua_clonetag)(int32 t); #define lua_clonetag(t) lua_copytagmethods(lua_newtag(), (t)) - /* ========================================================================== ** for compatibility with old versions. Avoid using these macros/functions ** If your program does need any of these, define LUA_COMPAT2_5 @@ -160,34 +154,27 @@ int32 (lua_clonetag) (int32 t); #ifdef LUA_COMPAT2_5 - -lua_Object lua_setfallback (char *event, lua_CFunction fallback); +lua_Object lua_setfallback(char *event, lua_CFunction fallback); #define lua_storeglobal lua_setglobal -#define lua_type lua_tag - -#define lua_lockobject(o) lua_refobject(o,1) -#define lua_lock() lua_ref(1) -#define lua_getlocked lua_getref -#define lua_pushlocked lua_pushref -#define lua_unlock lua_unref +#define lua_type lua_tag +#define lua_lockobject(o) lua_refobject(o,1) +#define lua_lock() lua_ref(1) +#define lua_getlocked lua_getref +#define lua_pushlocked lua_pushref +#define lua_unlock lua_unref #define lua_pushliteral(o) lua_pushstring(o) - -#define lua_getindexed(o,n) (lua_pushobject(o), lua_pushnumber(n), lua_gettable()) -#define lua_getfield(o,f) (lua_pushobject(o), lua_pushstring(f), lua_gettable()) - -#define lua_copystring(o) (strdup(lua_getstring(o))) - -#define lua_getsubscript lua_gettable +#define lua_getindexed(o, n) (lua_pushobject(o), lua_pushnumber(n), lua_gettable()) +#define lua_getfield(o, f) (lua_pushobject(o), lua_pushstring(f), lua_gettable()) +#define lua_copystring(o) (strdup(lua_getstring(o))) +#define lua_getsubscript lua_gettable #define lua_storesubscript lua_settable #endif #endif - - /****************************************************************************** * Copyright (c) 1994-1998 TeCGraf, PUC-Rio. All rights reserved. * diff --git a/engine/lua/luadebug.h b/engine/lua/luadebug.h index 5cfd03f6123..031f4f9d937 100644 --- a/engine/lua/luadebug.h +++ b/engine/lua/luadebug.h @@ -9,21 +9,20 @@ #define luadebug_h -#include "lua.h" +#include "engine/lua/lua.h" typedef lua_Object lua_Function; -typedef void (*lua_LHFunction) (int32 line); -typedef void (*lua_CHFunction) (lua_Function func, const char *file, int32 line); +typedef void (*lua_LHFunction)(int32 line); +typedef void (*lua_CHFunction)(lua_Function func, const char *file, int32 line); -lua_Function lua_stackedfunction (int32 level); -void lua_funcinfo (lua_Object func, const char **filename, int32 *linedefined); -int32 lua_currentline (lua_Function func); -const char *lua_getobjname (lua_Object o, const char **name); - -lua_Object lua_getlocal (lua_Function func, int32 local_number, char **name); -int32 lua_setlocal (lua_Function func, int32 local_number); +lua_Function lua_stackedfunction(int32 level); +void lua_funcinfo(lua_Object func, const char **filename, int32 *linedefined); +int32 lua_currentline(lua_Function func); +const char *lua_getobjname(lua_Object o, const char **name); +lua_Object lua_getlocal(lua_Function func, int32 local_number, char **name); +int32 lua_setlocal(lua_Function func, int32 local_number); extern lua_LHFunction lua_linehook; extern lua_CHFunction lua_callhook; diff --git a/engine/lua/lualib.h b/engine/lua/lualib.h index 93da82aaca5..b0adff562e8 100644 --- a/engine/lua/lualib.h +++ b/engine/lua/lualib.h @@ -8,27 +8,21 @@ #ifndef lualib_h #define lualib_h -#include "lua.h" +#include "engine/lua/lua.h" +void lua_iolibopen(); +void lua_strlibopen(); +void lua_mathlibopen(); -void lua_iolibopen (void); -void lua_strlibopen (void); -void lua_mathlibopen (void); +// To keep compatibility with old versions - - - -/* To keep compatibility with old versions */ - -#define iolib_open lua_iolibopen -#define strlib_open lua_strlibopen +#define iolib_open lua_iolibopen +#define strlib_open lua_strlibopen #define mathlib_open lua_mathlibopen +// Auxiliary functions (private) - -/* Auxiliary functions (private) */ - -int32 luaI_singlematch (int32 c, const char *p, const char **ep); +int32 luaI_singlematch(int32 c, const char *p, const char **ep); #endif diff --git a/engine/lua/lundump.cpp b/engine/lua/lundump.cpp index 0d9eaa54786..aa957635b97 100644 --- a/engine/lua/lundump.cpp +++ b/engine/lua/lundump.cpp @@ -66,7 +66,7 @@ static byte *LoadCode(ZIO *Z) { luaL_verror("code too long (%ld bytes) in %s", size, zname(Z)); b = luaM_malloc(size); LoadBlock(b, size, Z); - return (Byte *)b; + return (byte *)b; } static TaggedString *LoadTString(ZIO *Z) { diff --git a/engine/lua/lvm.cpp b/engine/lua/lvm.cpp index 52d411a6d30..8b57a33cc13 100644 --- a/engine/lua/lvm.cpp +++ b/engine/lua/lvm.cpp @@ -5,750 +5,737 @@ */ -#include "lauxlib.h" -#include "ldo.h" -#include "lfunc.h" -#include "lgc.h" -#include "lmem.h" -#include "lopcodes.h" -#include "lstate.h" -#include "lstring.h" -#include "ltable.h" -#include "ltm.h" -#include "luadebug.h" -#include "lvm.h" +#include "engine/lua/lauxlib.h" +#include "engine/lua/ldo.h" +#include "engine/lua/lfunc.h" +#include "engine/lua/lgc.h" +#include "engine/lua/lmem.h" +#include "engine/lua/lopcodes.h" +#include "engine/lua/lstate.h" +#include "engine/lua/lstring.h" +#include "engine/lua/ltable.h" +#include "engine/lua/ltm.h" +#include "engine/lua/luadebug.h" +#include "engine/lua/lvm.h" +#define skip_word(pc) (pc += 2) +#define get_word(pc) ((*((pc) + 1) << 8)|(*(pc))) +#define next_word(pc) (pc += 2, get_word(pc - 2)) -#define skip_word(pc) (pc+=2) - -#define get_word(pc) ((*((pc)+1)<<8)|(*(pc))) - -#define next_word(pc) (pc+=2, get_word(pc-2)) - - -static TaggedString *strconc (TaggedString *l, TaggedString *r) -{ - size_t nl = l->u.s.len; - size_t nr = r->u.s.len; - char *buffer = luaL_openspace(nl+nr+1); - memcpy(buffer, l->str, nl); - memcpy(buffer+nl, r->str, nr); - return luaS_newlstr(buffer, nl+nr); +static TaggedString *strconc(TaggedString *l, TaggedString *r) { + size_t nl = l->u.s.len; + size_t nr = r->u.s.len; + char *buffer = luaL_openspace(nl + nr + 1); + memcpy(buffer, l->str, nl); + memcpy(buffer + nl, r->str, nr); + return luaS_newlstr(buffer, nl + nr); } +int32 luaV_tonumber (TObject *obj) { // LUA_NUMBER + double t; + char c; -int32 luaV_tonumber (TObject *obj) -{ /* LUA_NUMBER */ - double t; - char c; - if (ttype(obj) != LUA_T_STRING) - return 1; - else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) { - nvalue(obj) = (real)t; - ttype(obj) = LUA_T_NUMBER; - return 0; - } - else - return 2; + if (ttype(obj) != LUA_T_STRING) + return 1; + else if (sscanf(svalue(obj), "%lf %c",&t, &c) == 1) { + nvalue(obj) = (real)t; + ttype(obj) = LUA_T_NUMBER; + return 0; + } else + return 2; } - -int32 luaV_tostring (TObject *obj) -{ /* LUA_NUMBER */ - /* The Lua scripts for Grim Fandango sometimes end up executing - str..nil. The nil shows up in the original engine as "(nil)"... */ - if (ttype(obj) == LUA_T_NIL) { - tsvalue(obj) = luaS_new("(nil)"); - ttype(obj) = LUA_T_STRING; - return 0; - } - else if (ttype(obj) != LUA_T_NUMBER) - return 1; - else { - char s[60]; - real f = nvalue(obj); - int32 i; - if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i=(int32)f) == f) - sprintf (s, "%d", (int)i); - else - sprintf (s, NUMBER_FMT, nvalue(obj)); - tsvalue(obj) = luaS_new(s); - ttype(obj) = LUA_T_STRING; - return 0; - } +int32 luaV_tostring (TObject *obj) { // LUA_NUMBER + // The Lua scripts for Grim Fandango sometimes end up executing + // str..nil. The nil shows up in the original engine as "(nil)"... + if (ttype(obj) == LUA_T_NIL) { + tsvalue(obj) = luaS_new("(nil)"); + ttype(obj) = LUA_T_STRING; + return 0; + } else if (ttype(obj) != LUA_T_NUMBER) + return 1; + else { + char s[60]; + real f = nvalue(obj); + int32 i; + if ((real)(-MAX_INT) <= f && f <= (real)MAX_INT && (real)(i = (int32)f) == f) + sprintf (s, "%d", (int)i); + else + sprintf (s, NUMBER_FMT, nvalue(obj)); + tsvalue(obj) = luaS_new(s); + ttype(obj) = LUA_T_STRING; + return 0; + } } - -void luaV_closure (int32 nelems) -{ - if (nelems > 0) { - struct Stack *S = &L->stack; - Closure *c = luaF_newclosure(nelems); - c->consts[0] = *(S->top-1); - memcpy(&c->consts[1], S->top-(nelems+1), nelems*sizeof(TObject)); - S->top -= nelems; - ttype(S->top-1) = LUA_T_CLOSURE; - (S->top-1)->value.cl = c; - } +void luaV_closure(int32 nelems) { + if (nelems > 0) { + Stack *S = &L->stack; + Closure *c = luaF_newclosure(nelems); + c->consts[0] = *(S->top - 1); + memcpy(&c->consts[1], S->top - (nelems + 1), nelems * sizeof(TObject)); + S->top -= nelems; + ttype(S->top - 1) = LUA_T_CLOSURE; + (S->top - 1)->value.cl = c; + } } - /* ** Function to index a table. ** Receives the table at top-2 and the index at top-1. */ -void luaV_gettable (void) -{ - struct Stack *S = &L->stack; - TObject *im; - if (ttype(S->top-2) != LUA_T_ARRAY) /* not a table, get "gettable" method */ - im = luaT_getimbyObj(S->top-2, IM_GETTABLE); - else { /* object is a table... */ - int32 tg = (S->top-2)->value.a->htag; - im = luaT_getim(tg, IM_GETTABLE); - if (ttype(im) == LUA_T_NIL) { /* and does not have a "gettable" method */ - TObject *h = luaH_get(avalue(S->top-2), S->top-1); - if (h != NULL && ttype(h) != LUA_T_NIL) { - --S->top; - *(S->top-1) = *h; - } - else if (ttype(im=luaT_getim(tg, IM_INDEX)) != LUA_T_NIL) - luaD_callTM(im, 2, 1); - else { - --S->top; - ttype(S->top-1) = LUA_T_NIL; - } - return; - } - /* else it has a "gettable" method, go through to next command */ - } - /* object is not a table, or it has a "gettable" method */ - if (ttype(im) != LUA_T_NIL) - luaD_callTM(im, 2, 1); - else - lua_error("indexed expression not a table"); +void luaV_gettable() { + Stack *S = &L->stack; + TObject *im; + if (ttype(S->top - 2) != LUA_T_ARRAY) // not a table, get "gettable" method + im = luaT_getimbyObj(S->top - 2, IM_GETTABLE); + else { // object is a table... + int32 tg = (S->top - 2)->value.a->htag; + im = luaT_getim(tg, IM_GETTABLE); + if (ttype(im) == LUA_T_NIL) { // and does not have a "gettable" method + TObject *h = luaH_get(avalue(S->top - 2), S->top - 1); + if (h && ttype(h) != LUA_T_NIL) { + --S->top; + *(S->top - 1) = *h; + } else if (ttype(im = luaT_getim(tg, IM_INDEX)) != LUA_T_NIL) + luaD_callTM(im, 2, 1); + else { + --S->top; + ttype(S->top - 1) = LUA_T_NIL; + } + return; + } + // else it has a "gettable" method, go through to next command + } + // object is not a table, or it has a "gettable" method + if (ttype(im) != LUA_T_NIL) + luaD_callTM(im, 2, 1); + else + lua_error("indexed expression not a table"); } - /* ** Function to store indexed based on values at the stack.top ** mode = 0: raw store (without tag methods) ** mode = 1: normal store (with tag methods) ** mode = 2: "deep L->stack.stack" store (with tag methods) */ -void luaV_settable (TObject *t, int32 mode) -{ - struct Stack *S = &L->stack; - TObject *im = (mode == 0) ? NULL : luaT_getimbyObj(t, IM_SETTABLE); - if (ttype(t) == LUA_T_ARRAY && (im == NULL || ttype(im) == LUA_T_NIL)) { - TObject *h = luaH_set(avalue(t), t+1); - *h = *(S->top-1); - S->top -= (mode == 2) ? 1 : 3; - } - else { /* object is not a table, and/or has a specific "settable" method */ - if (im && ttype(im) != LUA_T_NIL) { - if (mode == 2) { - *(S->top+1) = *(L->stack.top-1); - *(S->top) = *(t+1); - *(S->top-1) = *t; - S->top += 2; /* WARNING: caller must assure stack space */ - } - luaD_callTM(im, 3, 0); - } - else - lua_error("indexed expression not a table"); - } +void luaV_settable(TObject *t, int32 mode) { + struct Stack *S = &L->stack; + TObject *im = (mode == 0) ? NULL : luaT_getimbyObj(t, IM_SETTABLE); + if (ttype(t) == LUA_T_ARRAY && (!im || ttype(im) == LUA_T_NIL)) { + TObject *h = luaH_set(avalue(t), t + 1); + *h = *(S->top - 1); + S->top -= (mode == 2) ? 1 : 3; + } else { // object is not a table, and/or has a specific "settable" method + if (im && ttype(im) != LUA_T_NIL) { + if (mode == 2) { + *(S->top + 1) = *(L->stack.top - 1); + *(S->top) = *(t + 1); + *(S->top - 1) = *t; + S->top += 2; // WARNING: caller must assure stack space + } + luaD_callTM(im, 3, 0); + } else + lua_error("indexed expression not a table"); + } +} + +void luaV_getglobal(TaggedString *ts) { + // WARNING: caller must assure stack space + TObject *value = &ts->u.s.globalval; + TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL); + if (ttype(im) == LUA_T_NIL) { // default behavior + *L->stack.top++ = *value; + } else { + Stack *S = &L->stack; + ttype(S->top) = LUA_T_STRING; + tsvalue(S->top) = ts; + S->top++; + *S->top++ = *value; + luaD_callTM(im, 2, 1); + } +} + +void luaV_setglobal(TaggedString *ts) { + TObject *oldvalue = &ts->u.s.globalval; + TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL); + if (ttype(im) == LUA_T_NIL) // default behavior */ + luaS_rawsetglobal(ts, --L->stack.top); + else { + // WARNING: caller must assure stack space + Stack *S = &L->stack; + TObject newvalue = *(S->top - 1); + ttype(S->top - 1) = LUA_T_STRING; + tsvalue(S->top - 1) = ts; + *S->top++ = *oldvalue; + *S->top++ = newvalue; + luaD_callTM(im, 3, 0); + } +} + +static void call_binTM(IMS event, const char *msg) { + TObject *im = luaT_getimbyObj(L->stack.top - 2, event); // try first operand + if (ttype(im) == LUA_T_NIL) { + im = luaT_getimbyObj(L->stack.top - 1, event); // try second operand + if (ttype(im) == LUA_T_NIL) { + im = luaT_getim(0, event); // try a 'global' i.m. + if (ttype(im) == LUA_T_NIL) + lua_error(msg); + } + } + lua_pushstring(luaT_eventname[event]); + luaD_callTM(im, 3, 1); } -void luaV_getglobal (TaggedString *ts) -{ - /* WARNING: caller must assure stack space */ - TObject *value = &ts->u.s.globalval; - TObject *im = luaT_getimbyObj(value, IM_GETGLOBAL); - if (ttype(im) == LUA_T_NIL) { /* default behavior */ - *L->stack.top++ = *value; - } - else { - struct Stack *S = &L->stack; - ttype(S->top) = LUA_T_STRING; - tsvalue(S->top) = ts; - S->top++; - *S->top++ = *value; - luaD_callTM(im, 2, 1); - } +static void call_arith(IMS event) { + call_binTM(event, "unexpected type in arithmetic operation"); } - -void luaV_setglobal (TaggedString *ts) -{ - TObject *oldvalue = &ts->u.s.globalval; - TObject *im = luaT_getimbyObj(oldvalue, IM_SETGLOBAL); - if (ttype(im) == LUA_T_NIL) /* default behavior */ - luaS_rawsetglobal(ts, --L->stack.top); - else { - /* WARNING: caller must assure stack space */ - struct Stack *S = &L->stack; - TObject newvalue = *(S->top-1); - ttype(S->top-1) = LUA_T_STRING; - tsvalue(S->top-1) = ts; - *S->top++ = *oldvalue; - *S->top++ = newvalue; - luaD_callTM(im, 3, 0); - } +static int32 strcomp(char *l, int32 ll, char *r, int32 lr) { + for (;;) { + int32 temp = (int32)strcoll(l, r); + if (temp != 0) + return temp; + // strings are equal up to a '\0' + temp = strlen(l); // index of first '\0' in both strings + if (temp == ll) // l is finished? + return (temp == lr) ? 0 : -1; // l is equal or smaller than r + else if (temp == lr) // r is finished? + return 1; // l is greater than r (because l is not finished) + // both strings longer than temp; go on comparing (after the '\0') + temp++; + l += temp; + ll -= temp; + r += temp; + lr -= temp; + } } - -static void call_binTM (IMS event, const char *msg) -{ - TObject *im = luaT_getimbyObj(L->stack.top-2, event);/* try first operand */ - if (ttype(im) == LUA_T_NIL) { - im = luaT_getimbyObj(L->stack.top-1, event); /* try second operand */ - if (ttype(im) == LUA_T_NIL) { - im = luaT_getim(0, event); /* try a 'global' i.m. */ - if (ttype(im) == LUA_T_NIL) - lua_error(msg); - } - } - lua_pushstring(luaT_eventname[event]); - luaD_callTM(im, 3, 1); +static void comparison(lua_Type ttype_less, lua_Type ttype_equal, lua_Type ttype_great, IMS op) { + Stack *S = &L->stack; + TObject *l = S->top-2; + TObject *r = S->top-1; + int32 result; + if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) + result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; + else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) + result = (int32)strcomp(svalue(l), tsvalue(l)->u.s.len, svalue(r), tsvalue(r)->u.s.len); + else { + call_binTM(op, "unexpected type in comparison"); + return; + } + S->top--; + nvalue(S->top - 1) = 1; + ttype(S->top - 1) = (result < 0) ? ttype_less : (result == 0) ? ttype_equal : ttype_great; } - -static void call_arith (IMS event) -{ - call_binTM(event, "unexpected type in arithmetic operation"); +void luaV_pack(StkId firstel, int32 nvararg, TObject *tab) { + TObject *firstelem = L->stack.stack + firstel; + int32 i; + if (nvararg < 0) + nvararg = 0; + avalue(tab) = luaH_new(nvararg + 1); // +1 for field 'n' + ttype(tab) = LUA_T_ARRAY; + for (i = 0; i < nvararg; i++) { + TObject index; + ttype(&index) = LUA_T_NUMBER; + nvalue(&index) = (real)i + 1; + *(luaH_set(avalue(tab), &index)) = *(firstelem + i); + } + // store counter in field "n" */ + { + TObject index, extra; + ttype(&index) = LUA_T_STRING; + tsvalue(&index) = luaS_new("n"); + ttype(&extra) = LUA_T_NUMBER; + nvalue(&extra) = (real)nvararg; + *(luaH_set(avalue(tab), &index)) = extra; + } } - -static int32 strcomp (char *l, int32 ll, char *r, int32 lr) -{ - for (;;) { - int32 temp = (int32)strcoll(l, r); - if (temp != 0) return temp; - /* strings are equal up to a '\0' */ - temp = strlen(l); /* index of first '\0' in both strings */ - if (temp == ll) /* l is finished? */ - return (temp == lr) ? 0 : -1; /* l is equal or smaller than r */ - else if (temp == lr) /* r is finished? */ - return 1; /* l is greater than r (because l is not finished) */ - /* both strings longer than temp; go on comparing (after the '\0') */ - temp++; - l += temp; ll -= temp; r += temp; lr -= temp; - } -} - -static void comparison (lua_Type ttype_less, lua_Type ttype_equal, - lua_Type ttype_great, IMS op) -{ - struct Stack *S = &L->stack; - TObject *l = S->top-2; - TObject *r = S->top-1; - int32 result; - if (ttype(l) == LUA_T_NUMBER && ttype(r) == LUA_T_NUMBER) - result = (nvalue(l) < nvalue(r)) ? -1 : (nvalue(l) == nvalue(r)) ? 0 : 1; - else if (ttype(l) == LUA_T_STRING && ttype(r) == LUA_T_STRING) - result = (int32)strcomp(svalue(l), tsvalue(l)->u.s.len, - svalue(r), tsvalue(r)->u.s.len); - else { - call_binTM(op, "unexpected type in comparison"); - return; - } - S->top--; - nvalue(S->top-1) = 1; - ttype(S->top-1) = (result < 0) ? ttype_less : - (result == 0) ? ttype_equal : ttype_great; -} - - -void luaV_pack (StkId firstel, int32 nvararg, TObject *tab) -{ - TObject *firstelem = L->stack.stack+firstel; - int32 i; - if (nvararg < 0) nvararg = 0; - avalue(tab) = luaH_new(nvararg+1); /* +1 for field 'n' */ - ttype(tab) = LUA_T_ARRAY; - for (i=0; ibase_ci; - struct Stack *S = &L->stack; /* to optimize */ - Closure *cl; - TProtoFunc *tf; - StkId base; - Byte *pc; - TObject *consts; - newfunc: - cl = L->ci->c; - tf = L->ci->tf; - base = L->ci->base; - if (S->top-S->stack > base && ttype(S->stack+base) == LUA_T_LINE) - base++; - pc = L->ci->pc; - consts = tf->consts; - while (1) { - int32 aux; - switch ((OpCode)(aux = *pc++)) { - - case PUSHNIL0: - ttype(S->top++) = LUA_T_NIL; - break; - - case PUSHNIL: - aux = *pc++; - do { - ttype(S->top++) = LUA_T_NIL; - } while (aux--); - break; - - case PUSHNUMBER: - aux = *pc++; goto pushnumber; - - case PUSHNUMBERW: - aux = next_word(pc); goto pushnumber; - - case PUSHNUMBER0: case PUSHNUMBER1: case PUSHNUMBER2: - aux -= PUSHNUMBER0; - pushnumber: - ttype(S->top) = LUA_T_NUMBER; - nvalue(S->top) = (real)aux; - S->top++; - break; - - case PUSHLOCAL: - aux = *pc++; goto pushlocal; - - case PUSHLOCAL0: case PUSHLOCAL1: case PUSHLOCAL2: case PUSHLOCAL3: - case PUSHLOCAL4: case PUSHLOCAL5: case PUSHLOCAL6: case PUSHLOCAL7: - aux -= PUSHLOCAL0; - pushlocal: - *S->top++ = *((S->stack+base) + aux); - break; - - case GETGLOBALW: - aux = next_word(pc); goto getglobal; - - case GETGLOBAL: - aux = *pc++; goto getglobal; - - case GETGLOBAL0: case GETGLOBAL1: case GETGLOBAL2: case GETGLOBAL3: - case GETGLOBAL4: case GETGLOBAL5: case GETGLOBAL6: case GETGLOBAL7: - aux -= GETGLOBAL0; - getglobal: - luaV_getglobal(tsvalue(&consts[aux])); - break; - - case GETTABLE: - luaV_gettable(); - break; - - case GETDOTTEDW: - aux = next_word(pc); goto getdotted; - - case GETDOTTED: - aux = *pc++; goto getdotted; - - case GETDOTTED0: case GETDOTTED1: case GETDOTTED2: case GETDOTTED3: - case GETDOTTED4: case GETDOTTED5: case GETDOTTED6: case GETDOTTED7: - aux -= GETDOTTED0; - getdotted: - *S->top++ = consts[aux]; - luaV_gettable(); - break; - - case PUSHSELFW: - aux = next_word(pc); goto pushself; - - case PUSHSELF: - aux = *pc++; goto pushself; - - case PUSHSELF0: case PUSHSELF1: case PUSHSELF2: case PUSHSELF3: - case PUSHSELF4: case PUSHSELF5: case PUSHSELF6: case PUSHSELF7: - aux -= PUSHSELF0; - pushself: { - TObject receiver = *(S->top-1); - *S->top++ = consts[aux]; - luaV_gettable(); - *S->top++ = receiver; - break; - } - - case PUSHCONSTANTW: - aux = next_word(pc); goto pushconstant; - - case PUSHCONSTANT: - aux = *pc++; goto pushconstant; - - case PUSHCONSTANT0: case PUSHCONSTANT1: case PUSHCONSTANT2: - case PUSHCONSTANT3: case PUSHCONSTANT4: case PUSHCONSTANT5: - case PUSHCONSTANT6: case PUSHCONSTANT7: - aux -= PUSHCONSTANT0; - pushconstant: - *S->top++ = consts[aux]; - break; - - case PUSHUPVALUE: - aux = *pc++; goto pushupvalue; - - case PUSHUPVALUE0: case PUSHUPVALUE1: - aux -= PUSHUPVALUE0; - pushupvalue: - *S->top++ = cl->consts[aux+1]; - break; - - case SETLOCAL: - aux = *pc++; goto setlocal; - - case SETLOCAL0: case SETLOCAL1: case SETLOCAL2: case SETLOCAL3: - case SETLOCAL4: case SETLOCAL5: case SETLOCAL6: case SETLOCAL7: - aux -= SETLOCAL0; - setlocal: - *((S->stack+base) + aux) = *(--S->top); - break; - - case SETGLOBALW: - aux = next_word(pc); goto setglobal; - - case SETGLOBAL: - aux = *pc++; goto setglobal; - - case SETGLOBAL0: case SETGLOBAL1: case SETGLOBAL2: case SETGLOBAL3: - case SETGLOBAL4: case SETGLOBAL5: case SETGLOBAL6: case SETGLOBAL7: - aux -= SETGLOBAL0; - setglobal: - luaV_setglobal(tsvalue(&consts[aux])); - break; - - case SETTABLE0: - luaV_settable(S->top-3, 1); - break; - - case SETTABLE: - luaV_settable(S->top-3-(*pc++), 2); - break; - - case SETLISTW: - aux = next_word(pc); aux *= LFIELDS_PER_FLUSH; goto setlist; - - case SETLIST: - aux = *(pc++) * LFIELDS_PER_FLUSH; goto setlist; - - case SETLIST0: - aux = 0; - setlist: { - int32 n = *(pc++); - TObject *arr = S->top-n-1; - for (; n; n--) { - ttype(S->top) = LUA_T_NUMBER; - nvalue(S->top) = (real)(n+aux); - *(luaH_set(avalue(arr), S->top)) = *(S->top-1); - S->top--; - } - break; - } - - case SETMAP0: - aux = 0; goto setmap; - - case SETMAP: - aux = *pc++; - setmap: { - TObject *arr = S->top-(2*aux)-3; - do { - *(luaH_set(avalue(arr), S->top-2)) = *(S->top-1); - S->top-=2; - } while (aux--); - break; - } - - case POP: - aux = *pc++; goto pop; - - case POP0: case POP1: - aux -= POP0; - pop: - S->top -= (aux+1); - break; - - case CREATEARRAYW: - aux = next_word(pc); goto createarray; - - case CREATEARRAY0: case CREATEARRAY1: - aux -= CREATEARRAY0; goto createarray; - - case CREATEARRAY: - aux = *pc++; - createarray: - luaC_checkGC(); - avalue(S->top) = luaH_new(aux); - ttype(S->top) = LUA_T_ARRAY; - S->top++; - break; - - case EQOP: case NEQOP: { - int32 res = luaO_equalObj(S->top-2, S->top-1); - S->top--; - if (aux == NEQOP) res = !res; - ttype(S->top-1) = res ? LUA_T_NUMBER : LUA_T_NIL; - nvalue(S->top-1) = 1; - break; - } - - case LTOP: - comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); - break; - - case LEOP: - comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); - break; - - case GTOP: - comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); - break; - - case GEOP: - comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); - break; - - case ADDOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(IM_ADD); - else { - nvalue(l) += nvalue(r); - --S->top; - } - break; - } - - case SUBOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(IM_SUB); - else { - nvalue(l) -= nvalue(r); - --S->top; - } - break; - } - - case MULTOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(IM_MUL); - else { - nvalue(l) *= nvalue(r); - --S->top; - } - break; - } - - case DIVOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tonumber(r) || tonumber(l)) - call_arith(IM_DIV); - else { - nvalue(l) /= nvalue(r); - --S->top; - } - break; - } - - case POWOP: - call_binTM(IM_POW, "undefined operation"); - break; - - case CONCOP: { - TObject *l = S->top-2; - TObject *r = S->top-1; - if (tostring(l) || tostring(r)) - call_binTM(IM_CONCAT, "unexpected type for concatenation"); - else { - tsvalue(l) = strconc(tsvalue(l), tsvalue(r)); - --S->top; - } - luaC_checkGC(); - break; - } - - case MINUSOP: - if (tonumber(S->top-1)) { - ttype(S->top) = LUA_T_NIL; - S->top++; - call_arith(IM_UNM); - } - else - nvalue(S->top-1) = - nvalue(S->top-1); - break; - - case NOTOP: - ttype(S->top-1) = - (ttype(S->top-1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; - nvalue(S->top-1) = 1; - break; - - case ONTJMPW: - aux = next_word(pc); goto ontjmp; - - case ONTJMP: - aux = *pc++; - ontjmp: - if (ttype(S->top-1) != LUA_T_NIL) pc += aux; - else S->top--; - break; - - case ONFJMPW: - aux = next_word(pc); goto onfjmp; - - case ONFJMP: - aux = *pc++; - onfjmp: - if (ttype(S->top-1) == LUA_T_NIL) pc += aux; - else S->top--; - break; - - case JMPW: - aux = next_word(pc); goto jmp; - - case JMP: - aux = *pc++; - jmp: - pc += aux; - break; - - case IFFJMPW: - aux = next_word(pc); goto iffjmp; - - case IFFJMP: - aux = *pc++; - iffjmp: - if (ttype(--S->top) == LUA_T_NIL) pc += aux; - break; - - case IFTUPJMPW: - aux = next_word(pc); goto iftupjmp; - - case IFTUPJMP: - aux = *pc++; - iftupjmp: - if (ttype(--S->top) != LUA_T_NIL) pc -= aux; - break; - - case IFFUPJMPW: - aux = next_word(pc); goto iffupjmp; - - case IFFUPJMP: - aux = *pc++; - iffupjmp: - if (ttype(--S->top) == LUA_T_NIL) pc -= aux; - break; - - case CLOSURE: - aux = *pc++; - goto closure; - - case CLOSURE0: - aux = 0; - goto closure; - - case CLOSURE1: - aux = 1; - closure: - luaV_closure(aux); - luaC_checkGC(); - break; - - case CALLFUNC: - aux = *pc++; goto callfunc; - - case CALLFUNC0: case CALLFUNC1: - aux -= CALLFUNC0; - callfunc: { - StkId newBase = (S->top-S->stack)-(*pc++); - TObject *func = S->stack+newBase-1; - L->ci->pc = pc; - if (ttype(func) == LUA_T_PROTO || - (ttype(func) == LUA_T_CLOSURE && - ttype(&clvalue(func)->consts[0]) == LUA_T_PROTO)) { - - /* Calling another Lua function */ - luaD_precall(func, newBase, aux); - ttype(func) = (ttype(func) == LUA_T_PROTO) ? - LUA_T_PMARK : LUA_T_CLMARK; - goto newfunc; - } - luaD_call(newBase, aux); - - if (L->Tstate != RUN) { - if (ci_index > 1) /* C functions detected by break_here */ - lua_error("Cannot yield through method call"); - return -1; - } - break; - } - - case ENDCODE: - S->top = S->stack + base; - /* goes through */ - case RETCODE: { - StkId firstResult = (base + ((aux==RETCODE) ? *pc : 0)); - if (lua_callhook) - luaD_callHook(base, NULL, 1); - /* If returning from the original stack frame, terminate */ - if (L->ci == L->base_ci + ci_index) - return firstResult; - luaD_postret(firstResult); - goto newfunc; - } - - case SETLINEW: - aux = next_word(pc); goto setline; - - case SETLINE: - aux = *pc++; - setline: - if ((S->stack+base-1)->ttype != LUA_T_LINE) { - /* open space for LINE value */ - luaD_openstack((S->top-S->stack)-base); - base++; - (S->stack+base-1)->ttype = LUA_T_LINE; - } - (S->stack+base-1)->value.i = aux; - if (lua_linehook) - luaD_lineHook(aux); - break; - -#ifdef DEBUG - default: - LUA_INTERNALERROR("opcode doesn't match"); +StkId luaV_execute(struct CallInfo *ci) { + // Save index in case CallInfo array is realloc'd + int32 ci_index = ci - L->base_ci; + struct Stack *S = &L->stack; // to optimize + Closure *cl; + TProtoFunc *tf; + StkId base; + byte *pc; + TObject *consts; +newfunc: + cl = L->ci->c; + tf = L->ci->tf; + base = L->ci->base; + if (S->top-S->stack > base && ttype(S->stack+base) == LUA_T_LINE) + base++; + pc = L->ci->pc; + consts = tf->consts; + while (1) { + int32 aux; + switch ((OpCode)(aux = *pc++)) { + case PUSHNIL0: + ttype(S->top++) = LUA_T_NIL; + break; + case PUSHNIL: + aux = *pc++; + do { + ttype(S->top++) = LUA_T_NIL; + } while (aux--); + break; + case PUSHNUMBER: + aux = *pc++; + goto pushnumber; + case PUSHNUMBERW: + aux = next_word(pc); + goto pushnumber; + case PUSHNUMBER0: + case PUSHNUMBER1: + case PUSHNUMBER2: + aux -= PUSHNUMBER0; +pushnumber: + ttype(S->top) = LUA_T_NUMBER; + nvalue(S->top) = (real)aux; + S->top++; + break; + case PUSHLOCAL: + aux = *pc++; + goto pushlocal; + case PUSHLOCAL0: + case PUSHLOCAL1: + case PUSHLOCAL2: + case PUSHLOCAL3: + case PUSHLOCAL4: + case PUSHLOCAL5: + case PUSHLOCAL6: + case PUSHLOCAL7: + aux -= PUSHLOCAL0; +pushlocal: + *S->top++ = *((S->stack + base) + aux); + break; + case GETGLOBALW: + aux = next_word(pc); + goto getglobal; + case GETGLOBAL: + aux = *pc++; + goto getglobal; + case GETGLOBAL0: + case GETGLOBAL1: + case GETGLOBAL2: + case GETGLOBAL3: + case GETGLOBAL4: + case GETGLOBAL5: + case GETGLOBAL6: + case GETGLOBAL7: + aux -= GETGLOBAL0; +getglobal: + luaV_getglobal(tsvalue(&consts[aux])); + break; + case GETTABLE: + luaV_gettable(); + break; + case GETDOTTEDW: + aux = next_word(pc); goto getdotted; + case GETDOTTED: + aux = *pc++; + goto getdotted; + case GETDOTTED0: + case GETDOTTED1: + case GETDOTTED2: + case GETDOTTED3: + case GETDOTTED4: + case GETDOTTED5: + case GETDOTTED6: + case GETDOTTED7: + aux -= GETDOTTED0; +getdotted: + *S->top++ = consts[aux]; + luaV_gettable(); + break; + case PUSHSELFW: + aux = next_word(pc); + goto pushself; + case PUSHSELF: + aux = *pc++; + goto pushself; + case PUSHSELF0: + case PUSHSELF1: + case PUSHSELF2: + case PUSHSELF3: + case PUSHSELF4: + case PUSHSELF5: + case PUSHSELF6: + case PUSHSELF7: + aux -= PUSHSELF0; +pushself: + { + TObject receiver = *(S->top - 1); + *S->top++ = consts[aux]; + luaV_gettable(); + *S->top++ = receiver; + break; + } + case PUSHCONSTANTW: + aux = next_word(pc); + goto pushconstant; + case PUSHCONSTANT: + aux = *pc++; goto pushconstant; + case PUSHCONSTANT0: + case PUSHCONSTANT1: + case PUSHCONSTANT2: + case PUSHCONSTANT3: + case PUSHCONSTANT4: + case PUSHCONSTANT5: + case PUSHCONSTANT6: + case PUSHCONSTANT7: + aux -= PUSHCONSTANT0; +pushconstant: + *S->top++ = consts[aux]; + break; + case PUSHUPVALUE: + aux = *pc++; + goto pushupvalue; + case PUSHUPVALUE0: + case PUSHUPVALUE1: + aux -= PUSHUPVALUE0; +pushupvalue: + *S->top++ = cl->consts[aux + 1]; + break; + case SETLOCAL: + aux = *pc++; + goto setlocal; + case SETLOCAL0: + case SETLOCAL1: + case SETLOCAL2: + case SETLOCAL3: + case SETLOCAL4: + case SETLOCAL5: + case SETLOCAL6: + case SETLOCAL7: + aux -= SETLOCAL0; +setlocal: + *((S->stack + base) + aux) = *(--S->top); + break; + case SETGLOBALW: + aux = next_word(pc); + goto setglobal; + case SETGLOBAL: + aux = *pc++; + goto setglobal; + case SETGLOBAL0: + case SETGLOBAL1: + case SETGLOBAL2: + case SETGLOBAL3: + case SETGLOBAL4: + case SETGLOBAL5: + case SETGLOBAL6: + case SETGLOBAL7: + aux -= SETGLOBAL0; +setglobal: + luaV_setglobal(tsvalue(&consts[aux])); + break; + case SETTABLE0: + luaV_settable(S->top - 3, 1); + break; + case SETTABLE: + luaV_settable(S->top - 3 - (*pc++), 2); + break; + case SETLISTW: + aux = next_word(pc); + aux *= LFIELDS_PER_FLUSH; + goto setlist; + case SETLIST: + aux = *(pc++) * LFIELDS_PER_FLUSH; + goto setlist; + case SETLIST0: + aux = 0; +setlist: + { + int32 n = *(pc++); + TObject *arr = S->top-n-1; + for (; n; n--) { + ttype(S->top) = LUA_T_NUMBER; + nvalue(S->top) = (real)(n + aux); + *(luaH_set(avalue(arr), S->top)) = *(S->top - 1); + S->top--; + } + break; + } + case SETMAP0: + aux = 0; + goto setmap; + case SETMAP: + aux = *pc++; +setmap: + { + TObject *arr = S->top-(2*aux)-3; + do { + *(luaH_set(avalue(arr), S->top - 2)) = *(S->top - 1); + S->top -= 2; + } while (aux--); + break; + } + case POP: + aux = *pc++; + goto pop; + case POP0: + case POP1: + aux -= POP0; +pop: + S->top -= (aux + 1); + break; + case CREATEARRAYW: + aux = next_word(pc); + goto createarray; + case CREATEARRAY0: + case CREATEARRAY1: + aux -= CREATEARRAY0; + goto createarray; + case CREATEARRAY: + aux = *pc++; +createarray: + luaC_checkGC(); + avalue(S->top) = luaH_new(aux); + ttype(S->top) = LUA_T_ARRAY; + S->top++; + break; + case EQOP: + case NEQOP: + { + int32 res = luaO_equalObj(S->top - 2, S->top - 1); + S->top--; + if (aux == NEQOP) + res = !res; + ttype(S->top - 1) = res ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(S->top - 1) = 1; + break; + } + case LTOP: + comparison(LUA_T_NUMBER, LUA_T_NIL, LUA_T_NIL, IM_LT); + break; + case LEOP: + comparison(LUA_T_NUMBER, LUA_T_NUMBER, LUA_T_NIL, IM_LE); + break; + case GTOP: + comparison(LUA_T_NIL, LUA_T_NIL, LUA_T_NUMBER, IM_GT); + break; + case GEOP: + comparison(LUA_T_NIL, LUA_T_NUMBER, LUA_T_NUMBER, IM_GE); + break; + case ADDOP: + { + TObject *l = S->top - 2; + TObject *r = S->top - 1; + if (tonumber(r) || tonumber(l)) + call_arith(IM_ADD); + else { + nvalue(l) += nvalue(r); + --S->top; + } + break; + } + case SUBOP: + { + TObject *l = S->top - 2; + TObject *r = S->top - 1; + if (tonumber(r) || tonumber(l)) + call_arith(IM_SUB); + else { + nvalue(l) -= nvalue(r); + --S->top; + } + break; + } + case MULTOP: + { + TObject *l = S->top - 2; + TObject *r = S->top - 1; + if (tonumber(r) || tonumber(l)) + call_arith(IM_MUL); + else { + nvalue(l) *= nvalue(r); + --S->top; + } + break; + } + case DIVOP: + { + TObject *l = S->top-2; + TObject *r = S->top-1; + if (tonumber(r) || tonumber(l)) + call_arith(IM_DIV); + else { + nvalue(l) /= nvalue(r); + --S->top; + } + break; + } + case POWOP: + call_binTM(IM_POW, "undefined operation"); + break; + case CONCOP: + { + TObject *l = S->top - 2; + TObject *r = S->top - 1; + if (tostring(l) || tostring(r)) + call_binTM(IM_CONCAT, "unexpected type for concatenation"); + else { + tsvalue(l) = strconc(tsvalue(l), tsvalue(r)); + --S->top; + } + luaC_checkGC(); + break; + } + case MINUSOP: + if (tonumber(S->top-1)) { + ttype(S->top) = LUA_T_NIL; + S->top++; + call_arith(IM_UNM); + } else + nvalue(S->top - 1) = - nvalue(S->top - 1); + break; + case NOTOP: + ttype(S->top - 1) = (ttype(S->top - 1) == LUA_T_NIL) ? LUA_T_NUMBER : LUA_T_NIL; + nvalue(S->top - 1) = 1; + break; + case ONTJMPW: + aux = next_word(pc); + goto ontjmp; + case ONTJMP: + aux = *pc++; +ontjmp: + if (ttype(S->top-1) != LUA_T_NIL) + pc += aux; + else + S->top--; + break; + case ONFJMPW: + aux = next_word(pc); + goto onfjmp; + case ONFJMP: + aux = *pc++; +onfjmp: + if (ttype(S->top - 1) == LUA_T_NIL) + pc += aux; + else + S->top--; + break; + case JMPW: + aux = next_word(pc); + goto jmp; + case JMP: + aux = *pc++; +jmp: + pc += aux; + break; + case IFFJMPW: + aux = next_word(pc); + goto iffjmp; + case IFFJMP: + aux = *pc++; +iffjmp: + if (ttype(--S->top) == LUA_T_NIL) + pc += aux; + break; + case IFTUPJMPW: + aux = next_word(pc); + goto iftupjmp; + case IFTUPJMP: + aux = *pc++; +iftupjmp: + if (ttype(--S->top) != LUA_T_NIL) + pc -= aux; + break; + case IFFUPJMPW: + aux = next_word(pc); + goto iffupjmp; + case IFFUPJMP: + aux = *pc++; +iffupjmp: + if (ttype(--S->top) == LUA_T_NIL) + pc -= aux; + break; + case CLOSURE: + aux = *pc++; + goto closure; + case CLOSURE0: + aux = 0; + goto closure; + case CLOSURE1: + aux = 1; +closure: + luaV_closure(aux); + luaC_checkGC(); + break; + case CALLFUNC: + aux = *pc++; + goto callfunc; + case CALLFUNC0: + case CALLFUNC1: + aux -= CALLFUNC0; +callfunc: + { + StkId newBase = (S->top-S->stack)-(*pc++); + TObject *func = S->stack+newBase-1; + L->ci->pc = pc; + if (ttype(func) == LUA_T_PROTO || (ttype(func) == LUA_T_CLOSURE && + ttype(&clvalue(func)->consts[0]) == LUA_T_PROTO)) { + + // Calling another Lua function + luaD_precall(func, newBase, aux); + ttype(func) = (ttype(func) == LUA_T_PROTO) ? LUA_T_PMARK : LUA_T_CLMARK; + goto newfunc; + } + luaD_call(newBase, aux); + + if (L->Tstate != RUN) { + if (ci_index > 1) // C functions detected by break_here + lua_error("Cannot yield through method call"); + return -1; + } + break; + } + case ENDCODE: + S->top = S->stack + base; + // goes through + case RETCODE: + { + StkId firstResult = (base + ((aux==RETCODE) ? *pc : 0)); + if (lua_callhook) + luaD_callHook(base, NULL, 1); + // If returning from the original stack frame, terminate + if (L->ci == L->base_ci + ci_index) + return firstResult; + luaD_postret(firstResult); + goto newfunc; + } + case SETLINEW: + aux = next_word(pc); + goto setline; + case SETLINE: + aux = *pc++; +setline: + if ((S->stack + base - 1)->ttype != LUA_T_LINE) { + // open space for LINE value */ + luaD_openstack((S->top - S->stack)-base); + base++; + (S->stack + base - 1)->ttype = LUA_T_LINE; + } + (S->stack + base - 1)->value.i = aux; + if (lua_linehook) + luaD_lineHook(aux); + break; +#ifdef LUA_DEBUG + default: + LUA_INTERNALERROR("opcode doesn't match"); #endif - } - } + } + } } diff --git a/engine/lua/lvm.h b/engine/lua/lvm.h index 49687e7ff2a..517ae3a6c09 100644 --- a/engine/lua/lvm.h +++ b/engine/lua/lvm.h @@ -8,22 +8,22 @@ #define lvm_h -#include "ldo.h" -#include "lobject.h" +#include "engine/lua/ldo.h" +#include "engine/lua/lobject.h" #define tonumber(o) ((ttype(o) != LUA_T_NUMBER) && (luaV_tonumber(o) != 0)) #define tostring(o) ((ttype(o) != LUA_T_STRING) && (luaV_tostring(o) != 0)) -void luaV_pack (StkId firstel, int32 nvararg, TObject *tab); -int32 luaV_tonumber (TObject *obj); -int32 luaV_tostring (TObject *obj); -void luaV_gettable (void); -void luaV_settable (TObject *t, int32 mode); -void luaV_getglobal (TaggedString *ts); -void luaV_setglobal (TaggedString *ts); -StkId luaV_execute (struct CallInfo *ci); -void luaV_closure (int32 nelems); +void luaV_pack(StkId firstel, int32 nvararg, TObject *tab); +int32 luaV_tonumber(TObject *obj); +int32 luaV_tostring(TObject *obj); +void luaV_gettable(); +void luaV_settable(TObject *t, int32 mode); +void luaV_getglobal(TaggedString *ts); +void luaV_setglobal(TaggedString *ts); +StkId luaV_execute(CallInfo *ci); +void luaV_closure(int32 nelems); #endif diff --git a/engine/lua/lzio.h b/engine/lua/lzio.h index f7d4621faad..59ce2a6ba2d 100644 --- a/engine/lua/lzio.h +++ b/engine/lua/lzio.h @@ -26,7 +26,7 @@ int32 zread(ZIO *z, void *b, int32 n); // read next n bytes int32 zgeteoz(ZIO *); #define zgetc(z) (--(z)->n >= 0 ? ((int32)*(z)->p++): zgeteoz(z)) -#define zungetc(z) (++(z)->n,--(z)->p) +#define zungetc(z) (++(z)->n, --(z)->p) #define zname(z) ((z)->name)