+
+
+static int isneg (const char **s) {
+ if (**s == '-') { (*s)++; return 1; }
+ else if (**s == '+') (*s)++;
+ return 0;
+}
+
+
+static lua_Number readhexa (const char **s, lua_Number r, int *count) {
+ for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
+ r = (r * 16.0) + cast_num(luaO_hexavalue(cast_uchar(**s)));
+ (*count)++;
+ }
+ return r;
+}
+
+
+/*
+** convert an hexadecimal numeric string to a number, following
+** C99 specification for 'strtod'
+*/
+static lua_Number lua_strx2number (const char *s, char **endptr) {
+ lua_Number r = 0.0;
+ int e = 0, i = 0;
+ int neg = 0; /* 1 if number is negative */
+ *endptr = cast(char *, s); /* nothing is valid yet */
+ while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
+ neg = isneg(&s); /* check signal */
+ if (!(*s == '0' && (*(s + 1) == 'x' || *(s + 1) == 'X'))) /* check '0x' */
+ return 0.0; /* invalid format (no '0x') */
+ s += 2; /* skip '0x' */
+ r = readhexa(&s, r, &i); /* read integer part */
+ if (*s == '.') {
+ s++; /* skip dot */
+ r = readhexa(&s, r, &e); /* read fractional part */
+ }
+ if (i == 0 && e == 0)
+ return 0.0; /* invalid format (no digit) */
+ e *= -4; /* each fractional digit divides value by 2^-4 */
+ *endptr = cast(char *, s); /* valid up to here */
+ if (*s == 'p' || *s == 'P') { /* exponent part? */
+ int exp1 = 0;
+ int neg1;
+ s++; /* skip 'p' */
+ neg1 = isneg(&s); /* signal */
+ if (!lisdigit(cast_uchar(*s)))
+ goto ret; /* must have at least one digit */
+ while (lisdigit(cast_uchar(*s))) /* read exponent */
+ exp1 = exp1 * 10 + *(s++) - '0';
+ if (neg1) exp1 = -exp1;
+ e += exp1;
+ }
+ *endptr = cast(char *, s); /* valid up to here */
+ ret:
+ if (neg) r = -r;
+ return ldexp(r, e);
+}
+
+#endif
+
+
+int luaO_str2d (const char *s, size_t len, lua_Number *result) {
char *endptr;
- *result = lua_str2number(s, &endptr);
- if (endptr == s) return 0; /* conversion failed */
- if (*endptr == 'x' || *endptr == 'X') /* maybe an hexadecimal constant? */
- *result = cast_num(strtoul(s, &endptr, 16));
- if (*endptr == '\0') return 1; /* most common case */
- while (isspace(cast(unsigned char, *endptr))) endptr++;
- if (*endptr != '\0') return 0; /* invalid trailing characters? */
- return 1;
+ if (strpbrk(s, "nN")) /* reject 'inf' and 'nan' */
+ return 0;
+ else if (strpbrk(s, "xX")) /* hexa? */
+ *result = lua_strx2number(s, &endptr);
+ else
+ *result = lua_str2number(s, &endptr);
+ if (endptr == s) return 0; /* nothing recognized */
+ while (lisspace(cast_uchar(*endptr))) endptr++;
+ return (endptr == s + len); /* OK if no trailing characters */
}
-static void pushstr (lua_State *L, const char *str) {
- setsvalue2s(L, L->top, luaS_new(L, str));
+static void pushstr (lua_State *L, const char *str, size_t l) {
+ setsvalue2s(L, L->top, luaS_newlstr(L, str, l));
incr_top(L);
}
/* this function handles only `%d', `%c', %f, %p, and `%s' formats */
const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
- int n = 1;
- pushstr(L, "");
+ int n = 0;
for (;;) {
const char *e = strchr(fmt, '%');
if (e == NULL) break;
@@ -121,14 +188,13 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
case 's': {
const char *s = va_arg(argp, char *);
if (s == NULL) s = "(null)";
- pushstr(L, s);
+ pushstr(L, s, strlen(s));
break;
}
case 'c': {
- char buff[2];
- buff[0] = cast(char, va_arg(argp, int));
- buff[1] = '\0';
- pushstr(L, buff);
+ char buff;
+ buff = cast(char, va_arg(argp, int));
+ pushstr(L, &buff, 1);
break;
}
case 'd': {
@@ -143,29 +209,25 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
}
case 'p': {
char buff[4*sizeof(void *) + 8]; /* should be enough space for a `%p' */
- sprintf(buff, "%p", va_arg(argp, void *));
- pushstr(L, buff);
+ int l = sprintf(buff, "%p", va_arg(argp, void *));
+ pushstr(L, buff, l);
break;
}
case '%': {
- pushstr(L, "%");
+ pushstr(L, "%", 1);
break;
}
default: {
- char buff[3];
- buff[0] = '%';
- buff[1] = *(e+1);
- buff[2] = '\0';
- pushstr(L, buff);
- break;
+ luaG_runerror(L,
+ "invalid option " LUA_QL("%%%c") " to " LUA_QL("lua_pushfstring"),
+ *(e + 1));
}
}
n += 2;
fmt = e+2;
}
- pushstr(L, fmt);
- luaV_concat(L, n+1, cast_int(L->top - L->base) - 1);
- L->top -= n;
+ pushstr(L, fmt, strlen(fmt));
+ if (n > 0) luaV_concat(L, n + 1);
return svalue(L->top - 1);
}
@@ -180,36 +242,48 @@ const char *luaO_pushfstring (lua_State *L, const char *fmt, ...) {
}
+/* number of chars of a literal string without the ending \0 */
+#define LL(x) (sizeof(x)/sizeof(char) - 1)
+
+#define RETS "..."
+#define PRE "[string \""
+#define POS "\"]"
+
+#define addstr(a,b,l) ( memcpy(a,b,(l) * sizeof(char)), a += (l) )
+
void luaO_chunkid (char *out, const char *source, size_t bufflen) {
- if (*source == '=') {
- strncpy(out, source+1, bufflen); /* remove first char */
- out[bufflen-1] = '\0'; /* ensures null termination */
+ size_t l = strlen(source);
+ if (*source == '=') { /* 'literal' source */
+ if (l <= bufflen) /* small enough? */
+ memcpy(out, source + 1, l * sizeof(char));
+ else { /* truncate it */
+ addstr(out, source + 1, bufflen - 1);
+ *out = '\0';
+ }
}
- else { /* out = "source", or "...source" */
- if (*source == '@') {
- size_t l;
- source++; /* skip the `@' */
- bufflen -= sizeof(" '...' ");
- l = strlen(source);
- strcpy(out, "");
- if (l > bufflen) {
- source += (l-bufflen); /* get last part of file name */
- strcat(out, "...");
- }
- strcat(out, source);
+ else if (*source == '@') { /* file name */
+ if (l <= bufflen) /* small enough? */
+ memcpy(out, source + 1, l * sizeof(char));
+ else { /* add '...' before rest of name */
+ addstr(out, RETS, LL(RETS));
+ bufflen -= LL(RETS);
+ memcpy(out, source + 1 + l - bufflen, bufflen * sizeof(char));
}
- else { /* out = [string "string"] */
- size_t len = strcspn(source, "\n\r"); /* stop at first newline */
- bufflen -= sizeof(" [string \"...\"] ");
- if (len > bufflen) len = bufflen;
- strcpy(out, "[string \"");
- if (source[len] != '\0') { /* must truncate? */
- strncat(out, source, len);
- strcat(out, "...");
- }
- else
- strcat(out, source);
- strcat(out, "\"]");
+ }
+ else { /* string; format as [string "source"] */
+ const char *nl = strchr(source, '\n'); /* find first new line (if any) */
+ addstr(out, PRE, LL(PRE)); /* add prefix */
+ bufflen -= LL(PRE RETS POS) + 1; /* save space for prefix+suffix+'\0' */
+ if (l < bufflen && nl == NULL) { /* small one-line source? */
+ addstr(out, source, l); /* keep it */
}
+ else {
+ if (nl != NULL) l = nl - source; /* stop at first newline */
+ if (l > bufflen) l = bufflen;
+ addstr(out, source, l);
+ addstr(out, RETS, LL(RETS));
+ }
+ memcpy(out, POS, (LL(POS) + 1) * sizeof(char));
}
}
+
diff --git a/l2detect/lua/lobject.h b/l2detect/lua/lobject.h
index f1e447e..06246bf 100644
--- a/l2detect/lua/lobject.h
+++ b/l2detect/lua/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.20.1.2 2008/08/06 13:29:48 roberto Exp $
+** $Id: lobject.h,v 2.64 2011/10/31 17:48:22 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -16,18 +16,44 @@
#include "lua.h"
-/* tags for values visible from Lua */
-#define LAST_TAG LUA_TTHREAD
-
-#define NUM_TAGS (LAST_TAG+1)
-
-
/*
** Extra tags for non-values
*/
-#define LUA_TPROTO (LAST_TAG+1)
-#define LUA_TUPVAL (LAST_TAG+2)
-#define LUA_TDEADKEY (LAST_TAG+3)
+#define LUA_TPROTO LUA_NUMTAGS
+#define LUA_TUPVAL (LUA_NUMTAGS+1)
+#define LUA_TDEADKEY (LUA_NUMTAGS+2)
+
+/*
+** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
+*/
+#define LUA_TOTALTAGS (LUA_TUPVAL+2)
+
+
+/*
+** tags for Tagged Values have the following use of bits:
+** bits 0-3: actual tag (a LUA_T* value)
+** bits 4-5: variant bits
+** bit 6: whether value is collectable
+*/
+
+/*
+** LUA_TFUNCTION variants:
+** 0 - Lua function
+** 1 - light C function
+** 2 - regular C function (closure)
+*/
+
+/* Variant tags for functions */
+#define LUA_TLCL (LUA_TFUNCTION | (0 << 4)) /* Lua closure */
+#define LUA_TLCF (LUA_TFUNCTION | (1 << 4)) /* light C function */
+#define LUA_TCCL (LUA_TFUNCTION | (2 << 4)) /* C closure */
+
+
+/* Bit mark for collectable types */
+#define BIT_ISCOLLECTABLE (1 << 6)
+
+/* mark a tag as collectable */
+#define ctb(t) ((t) | BIT_ISCOLLECTABLE)
/*
@@ -52,120 +78,166 @@ typedef struct GCheader {
-
/*
** Union of all Lua values
*/
-typedef union {
- GCObject *gc;
- void *p;
- lua_Number n;
- int b;
-} Value;
+typedef union Value Value;
+
+
+#define numfield lua_Number n; /* numbers */
+
/*
-** Tagged Values
+** Tagged Values. This is the basic representation of values in Lua,
+** an actual value plus a tag with its type.
*/
-#define TValuefields Value value; int tt
+#define TValuefields Value value_; int tt_
-typedef struct lua_TValue {
- TValuefields;
-} TValue;
+typedef struct lua_TValue TValue;
+
+
+/* macro defining a nil value */
+#define NILCONSTANT {NULL}, LUA_TNIL
+
+
+#define val_(o) ((o)->value_)
+#define num_(o) (val_(o).n)
+
+
+/* raw type tag of a TValue */
+#define rttype(o) ((o)->tt_)
+
+/* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */
+#define ttype(o) (rttype(o) & 0x3F)
+
+
+/* type tag of a TValue with no variants (bits 0-3) */
+#define ttypenv(o) (rttype(o) & 0x0F)
/* Macros to test type */
-#define ttisnil(o) (ttype(o) == LUA_TNIL)
-#define ttisnumber(o) (ttype(o) == LUA_TNUMBER)
-#define ttisstring(o) (ttype(o) == LUA_TSTRING)
-#define ttistable(o) (ttype(o) == LUA_TTABLE)
-#define ttisfunction(o) (ttype(o) == LUA_TFUNCTION)
-#define ttisboolean(o) (ttype(o) == LUA_TBOOLEAN)
-#define ttisuserdata(o) (ttype(o) == LUA_TUSERDATA)
-#define ttisthread(o) (ttype(o) == LUA_TTHREAD)
-#define ttislightuserdata(o) (ttype(o) == LUA_TLIGHTUSERDATA)
+#define checktag(o,t) (rttype(o) == (t))
+#define ttisnumber(o) checktag((o), LUA_TNUMBER)
+#define ttisnil(o) checktag((o), LUA_TNIL)
+#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
+#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
+#define ttisstring(o) checktag((o), ctb(LUA_TSTRING))
+#define ttistable(o) checktag((o), ctb(LUA_TTABLE))
+#define ttisfunction(o) (ttypenv(o) == LUA_TFUNCTION)
+#define ttisclosure(o) ((rttype(o) & 0x1F) == LUA_TFUNCTION)
+#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
+#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
+#define ttislcf(o) checktag((o), LUA_TLCF)
+#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))
+#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
+#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
+
+#define ttisequal(o1,o2) (rttype(o1) == rttype(o2))
/* Macros to access values */
-#define ttype(o) ((o)->tt)
-#define gcvalue(o) check_exp(iscollectable(o), (o)->value.gc)
-#define pvalue(o) check_exp(ttislightuserdata(o), (o)->value.p)
-#define nvalue(o) check_exp(ttisnumber(o), (o)->value.n)
-#define rawtsvalue(o) check_exp(ttisstring(o), &(o)->value.gc->ts)
+#define nvalue(o) check_exp(ttisnumber(o), num_(o))
+#define gcvalue(o) check_exp(iscollectable(o), val_(o).gc)
+#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
+#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts)
#define tsvalue(o) (&rawtsvalue(o)->tsv)
-#define rawuvalue(o) check_exp(ttisuserdata(o), &(o)->value.gc->u)
+#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)
#define uvalue(o) (&rawuvalue(o)->uv)
-#define clvalue(o) check_exp(ttisfunction(o), &(o)->value.gc->cl)
-#define hvalue(o) check_exp(ttistable(o), &(o)->value.gc->h)
-#define bvalue(o) check_exp(ttisboolean(o), (o)->value.b)
-#define thvalue(o) check_exp(ttisthread(o), &(o)->value.gc->th)
+#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
+#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
+#define clCvalue(o) check_exp(ttisCclosure(o), &val_(o).gc->cl.c)
+#define fvalue(o) check_exp(ttislcf(o), val_(o).f)
+#define hvalue(o) check_exp(ttistable(o), &val_(o).gc->h)
+#define bvalue(o) check_exp(ttisboolean(o), val_(o).b)
+#define thvalue(o) check_exp(ttisthread(o), &val_(o).gc->th)
+/* a dead value may get the 'gc' field, but cannot access its contents */
+#define deadvalue(o) check_exp(ttisdeadkey(o), cast(void *, val_(o).gc))
#define l_isfalse(o) (ttisnil(o) || (ttisboolean(o) && bvalue(o) == 0))
-/*
-** for internal debug only
-*/
-#define checkconsistency(obj) \
- lua_assert(!iscollectable(obj) || (ttype(obj) == (obj)->value.gc->gch.tt))
+
+#define iscollectable(o) (rttype(o) & BIT_ISCOLLECTABLE)
+
+
+/* Macros for internal tests */
+#define righttt(obj) (ttypenv(obj) == gcvalue(obj)->gch.tt)
#define checkliveness(g,obj) \
- lua_assert(!iscollectable(obj) || \
- ((ttype(obj) == (obj)->value.gc->gch.tt) && !isdead(g, (obj)->value.gc)))
+ lua_longassert(!iscollectable(obj) || \
+ (righttt(obj) && !isdead(g,gcvalue(obj))))
/* Macros to set values */
-#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
+#define settt_(o,t) ((o)->tt_=(t))
#define setnvalue(obj,x) \
- { TValue *i_o=(obj); i_o->value.n=(x); i_o->tt=LUA_TNUMBER; }
+ { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
+
+#define changenvalue(o,x) check_exp(ttisnumber(o), num_(o)=(x))
+
+#define setnilvalue(obj) settt_(obj, LUA_TNIL)
+
+#define setfvalue(obj,x) \
+ { TValue *io=(obj); val_(io).f=(x); settt_(io, LUA_TLCF); }
#define setpvalue(obj,x) \
- { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
+ { TValue *io=(obj); val_(io).p=(x); settt_(io, LUA_TLIGHTUSERDATA); }
#define setbvalue(obj,x) \
- { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
+ { TValue *io=(obj); val_(io).b=(x); settt_(io, LUA_TBOOLEAN); }
+
+#define setgcovalue(L,obj,x) \
+ { TValue *io=(obj); GCObject *i_g=(x); \
+ val_(io).gc=i_g; settt_(io, ctb(gch(i_g)->tt)); }
#define setsvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
- checkliveness(G(L),i_o); }
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TSTRING)); \
+ checkliveness(G(L),io); }
#define setuvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
- checkliveness(G(L),i_o); }
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TUSERDATA)); \
+ checkliveness(G(L),io); }
#define setthvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
- checkliveness(G(L),i_o); }
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTHREAD)); \
+ checkliveness(G(L),io); }
-#define setclvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
- checkliveness(G(L),i_o); }
+#define setclLvalue(L,obj,x) \
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TLCL)); \
+ checkliveness(G(L),io); }
+
+#define setclCvalue(L,obj,x) \
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TCCL)); \
+ checkliveness(G(L),io); }
#define sethvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
- checkliveness(G(L),i_o); }
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TTABLE)); \
+ checkliveness(G(L),io); }
#define setptvalue(L,obj,x) \
- { TValue *i_o=(obj); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
- checkliveness(G(L),i_o); }
+ { TValue *io=(obj); \
+ val_(io).gc=cast(GCObject *, (x)); settt_(io, ctb(LUA_TPROTO)); \
+ checkliveness(G(L),io); }
+#define setdeadvalue(obj) settt_(obj, LUA_TDEADKEY)
#define setobj(L,obj1,obj2) \
- { const TValue *o2=(obj2); TValue *o1=(obj1); \
- o1->value = o2->value; o1->tt=o2->tt; \
- checkliveness(G(L),o1); }
+ { const TValue *io2=(obj2); TValue *io1=(obj1); \
+ io1->value_ = io2->value_; io1->tt_ = io2->tt_; \
+ checkliveness(G(L),io1); }
/*
-** different types of sets, according to destination
+** different types of assignments, according to destination
*/
/* from stack to (same) stack */
@@ -183,18 +255,147 @@ typedef struct lua_TValue {
#define setobj2n setobj
#define setsvalue2n setsvalue
-#define setttype(obj, tt) (ttype(obj) = (tt))
-#define iscollectable(o) (ttype(o) >= LUA_TSTRING)
+/*
+** {======================================================
+** NaN Trick
+** =======================================================
+*/
+
+#if defined(LUA_NANTRICK) \
+ || defined(LUA_NANTRICK_LE) \
+ || defined(LUA_NANTRICK_BE)
+
+/*
+** numbers are represented in the 'd_' field. All other values have the
+** value (NNMARK | tag) in 'tt__'. A number with such pattern would be
+** a "signaled NaN", which is never generated by regular operations by
+** the CPU (nor by 'strtod')
+*/
+#if !defined(NNMARK)
+#define NNMARK 0x7FF7A500
+#define NNMASK 0x7FFFFF00
+#endif
+
+#undef TValuefields
+#undef NILCONSTANT
+
+#if defined(LUA_NANTRICK_LE)
+
+/* little endian */
+#define TValuefields \
+ union { struct { Value v__; int tt__; } i; double d__; } u
+#define NILCONSTANT {{{NULL}, tag2tt(LUA_TNIL)}}
+/* field-access macros */
+#define v_(o) ((o)->u.i.v__)
+#define d_(o) ((o)->u.d__)
+#define tt_(o) ((o)->u.i.tt__)
+
+#elif defined(LUA_NANTRICK_BE)
+
+/* big endian */
+#define TValuefields \
+ union { struct { int tt__; Value v__; } i; double d__; } u
+#define NILCONSTANT {{tag2tt(LUA_TNIL), {NULL}}}
+/* field-access macros */
+#define v_(o) ((o)->u.i.v__)
+#define d_(o) ((o)->u.d__)
+#define tt_(o) ((o)->u.i.tt__)
+
+#elif !defined(TValuefields)
+#error option 'LUA_NANTRICK' needs declaration for 'TValuefields'
+
+#endif
+
+
+/* correspondence with standard representation */
+#undef val_
+#define val_(o) v_(o)
+#undef num_
+#define num_(o) d_(o)
+
+
+#undef numfield
+#define numfield /* no such field; numbers are the entire struct */
+
+/* basic check to distinguish numbers from non-numbers */
+#undef ttisnumber
+#define ttisnumber(o) ((tt_(o) & NNMASK) != NNMARK)
+
+#define tag2tt(t) (NNMARK | (t))
+
+#undef rttype
+#define rttype(o) (ttisnumber(o) ? LUA_TNUMBER : tt_(o) & 0xff)
+
+#undef settt_
+#define settt_(o,t) (tt_(o) = tag2tt(t))
+
+#undef setnvalue
+#define setnvalue(obj,x) \
+ { TValue *io_=(obj); num_(io_)=(x); lua_assert(ttisnumber(io_)); }
+
+#undef setobj
+#define setobj(L,obj1,obj2) \
+ { const TValue *o2_=(obj2); TValue *o1_=(obj1); \
+ o1_->u = o2_->u; \
+ checkliveness(G(L),o1_); }
+
+
+/*
+** these redefinitions are not mandatory, but these forms are more efficient
+*/
+
+#undef checktag
+#define checktag(o,t) (tt_(o) == tag2tt(t))
+
+#undef ttisequal
+#define ttisequal(o1,o2) \
+ (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
+
+
+
+#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; }
+
+
+#else
+
+#define luai_checknum(L,o,c) { /* empty */ }
+
+#endif
+/* }====================================================== */
+
+
+
+/*
+** {======================================================
+** types and prototypes
+** =======================================================
+*/
+
+
+union Value {
+ GCObject *gc; /* collectable objects */
+ void *p; /* light userdata */
+ int b; /* booleans */
+ lua_CFunction f; /* light C functions */
+ numfield /* numbers */
+};
+
+
+struct lua_TValue {
+ TValuefields;
+};
typedef TValue *StkId; /* index to stack elements */
+
+
/*
-** String headers for string table
+** Header for string value; string bytes follow the end of this structure
*/
typedef union TString {
L_Umaxalign dummy; /* ensures maximum alignment for strings */
@@ -202,28 +403,53 @@ typedef union TString {
CommonHeader;
lu_byte reserved;
unsigned int hash;
- size_t len;
+ size_t len; /* number of characters in string */
} tsv;
} TString;
+/* get the actual string (array of bytes) from a TString */
#define getstr(ts) cast(const char *, (ts) + 1)
+
+/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(rawtsvalue(o))
-
+/*
+** Header for userdata; memory area follows the end of this structure
+*/
typedef union Udata {
L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
struct {
CommonHeader;
struct Table *metatable;
struct Table *env;
- size_t len;
+ size_t len; /* number of bytes */
} uv;
} Udata;
+/*
+** Description of an upvalue for function prototypes
+*/
+typedef struct Upvaldesc {
+ TString *name; /* upvalue name (for debug information) */
+ lu_byte instack; /* whether it is in stack */
+ lu_byte idx; /* index of upvalue (in stack or in outer function's list) */
+} Upvaldesc;
+
+
+/*
+** Description of a local variable for function prototypes
+** (used for debug information)
+*/
+typedef struct LocVar {
+ TString *varname;
+ int startpc; /* first point where variable is active */
+ int endpc; /* first point where variable is dead */
+} LocVar;
+
/*
** Function Prototypes
@@ -233,11 +459,12 @@ typedef struct Proto {
TValue *k; /* constants used by the function */
Instruction *code;
struct Proto **p; /* functions defined inside the function */
- int *lineinfo; /* map from opcodes to source lines */
- struct LocVar *locvars; /* information about local variables */
- TString **upvalues; /* upvalue names */
- TString *source;
- int sizeupvalues;
+ int *lineinfo; /* map from opcodes to source lines (debug information) */
+ LocVar *locvars; /* information about local variables (debug information) */
+ Upvaldesc *upvalues; /* upvalue information */
+ union Closure *cache; /* last created closure with this prototype */
+ TString *source; /* used for debug information */
+ int sizeupvalues; /* size of 'upvalues' */
int sizek; /* size of `k' */
int sizecode;
int sizelineinfo;
@@ -246,31 +473,16 @@ typedef struct Proto {
int linedefined;
int lastlinedefined;
GCObject *gclist;
- lu_byte nups; /* number of upvalues */
- lu_byte numparams;
+ lu_byte numparams; /* number of fixed parameters */
lu_byte is_vararg;
- lu_byte maxstacksize;
+ lu_byte maxstacksize; /* maximum stack used by this function */
} Proto;
-/* masks for new-style vararg */
-#define VARARG_HASARG 1
-#define VARARG_ISVARARG 2
-#define VARARG_NEEDSARG 4
-
-
-typedef struct LocVar {
- TString *varname;
- int startpc; /* first point where variable is active */
- int endpc; /* first point where variable is dead */
-} LocVar;
-
-
/*
-** Upvalues
+** Lua Upvalues
*/
-
typedef struct UpVal {
CommonHeader;
TValue *v; /* points to stack or to its own value */
@@ -289,20 +501,19 @@ typedef struct UpVal {
*/
#define ClosureHeader \
- CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist; \
- struct Table *env
+ CommonHeader; lu_byte isC; lu_byte nupvalues; GCObject *gclist
typedef struct CClosure {
ClosureHeader;
lua_CFunction f;
- TValue upvalue[1];
+ TValue upvalue[1]; /* list of upvalues */
} CClosure;
typedef struct LClosure {
ClosureHeader;
struct Proto *p;
- UpVal *upvals[1];
+ UpVal *upvals[1]; /* list of upvalues */
} LClosure;
@@ -312,8 +523,9 @@ typedef union Closure {
} Closure;
-#define iscfunction(o) (ttype(o) == LUA_TFUNCTION && clvalue(o)->c.isC)
-#define isLfunction(o) (ttype(o) == LUA_TFUNCTION && !clvalue(o)->c.isC)
+#define isLfunction(o) ttisLclosure(o)
+
+#define getproto(o) (clLvalue(o)->p)
/*
@@ -337,7 +549,7 @@ typedef struct Node {
typedef struct Table {
CommonHeader;
- lu_byte flags; /* 1<lsizenode))
+/*
+** (address of) a fixed nil value
+*/
#define luaO_nilobject (&luaO_nilobject_)
-LUAI_DATA const TValue luaO_nilobject_;
-#define ceillog2(x) (luaO_log2((x)-1) + 1)
+LUAI_DDEC const TValue luaO_nilobject_;
+
-LUAI_FUNC int luaO_log2 (unsigned int x);
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
-LUAI_FUNC int luaO_rawequalObj (const TValue *t1, const TValue *t2);
-LUAI_FUNC int luaO_str2d (const char *s, lua_Number *result);
+LUAI_FUNC int luaO_ceillog2 (unsigned int x);
+LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2);
+LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result);
+LUAI_FUNC int luaO_hexavalue (int c);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
LUAI_FUNC const char *luaO_pushfstring (lua_State *L, const char *fmt, ...);
diff --git a/l2detect/lua/lopcodes.c b/l2detect/lua/lopcodes.c
index 0735fb2..c19c65b 100644
--- a/l2detect/lua/lopcodes.c
+++ b/l2detect/lua/lopcodes.c
@@ -1,8 +1,7 @@
/*
-** $Id: lopcodes.c,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lopcodes.c,v 1.48 2011/04/19 16:22:13 roberto Exp $
** See Copyright Notice in lua.h
*/
-
#include "stdafx.h"
#define lopcodes_c
@@ -14,15 +13,16 @@
/* ORDER OP */
-const char *const luaP_opnames[NUM_OPCODES+1] = {
+LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"MOVE",
"LOADK",
+ "LOADKX",
"LOADBOOL",
"LOADNIL",
"GETUPVAL",
- "GETGLOBAL",
+ "GETTABUP",
"GETTABLE",
- "SETGLOBAL",
+ "SETTABUP",
"SETUPVAL",
"SETTABLE",
"NEWTABLE",
@@ -48,27 +48,29 @@ const char *const luaP_opnames[NUM_OPCODES+1] = {
"RETURN",
"FORLOOP",
"FORPREP",
+ "TFORCALL",
"TFORLOOP",
"SETLIST",
- "CLOSE",
"CLOSURE",
"VARARG",
+ "EXTRAARG",
NULL
};
#define opmode(t,a,b,c,m) (((t)<<7) | ((a)<<6) | ((b)<<4) | ((c)<<2) | (m))
-const lu_byte luaP_opmodes[NUM_OPCODES] = {
+LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
/* T A B C mode opcode */
- opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
+ opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_MOVE */
,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_LOADK */
+ ,opmode(0, 1, OpArgN, OpArgN, iABx) /* OP_LOADKX */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_LOADBOOL */
- ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LOADNIL */
+ ,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_LOADNIL */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_GETUPVAL */
- ,opmode(0, 1, OpArgK, OpArgN, iABx) /* OP_GETGLOBAL */
+ ,opmode(0, 1, OpArgU, OpArgK, iABC) /* OP_GETTABUP */
,opmode(0, 1, OpArgR, OpArgK, iABC) /* OP_GETTABLE */
- ,opmode(0, 0, OpArgK, OpArgN, iABx) /* OP_SETGLOBAL */
+ ,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABUP */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_SETUPVAL */
,opmode(0, 0, OpArgK, OpArgK, iABC) /* OP_SETTABLE */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_NEWTABLE */
@@ -87,17 +89,18 @@ const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_EQ */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LT */
,opmode(1, 0, OpArgK, OpArgK, iABC) /* OP_LE */
- ,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TEST */
+ ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TEST */
,opmode(1, 1, OpArgR, OpArgU, iABC) /* OP_TESTSET */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_CALL */
,opmode(0, 1, OpArgU, OpArgU, iABC) /* OP_TAILCALL */
,opmode(0, 0, OpArgU, OpArgN, iABC) /* OP_RETURN */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORLOOP */
,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_FORPREP */
- ,opmode(1, 0, OpArgN, OpArgU, iABC) /* OP_TFORLOOP */
+ ,opmode(0, 0, OpArgN, OpArgU, iABC) /* OP_TFORCALL */
+ ,opmode(0, 1, OpArgR, OpArgN, iAsBx) /* OP_TFORLOOP */
,opmode(0, 0, OpArgU, OpArgU, iABC) /* OP_SETLIST */
- ,opmode(0, 0, OpArgN, OpArgN, iABC) /* OP_CLOSE */
,opmode(0, 1, OpArgU, OpArgN, iABx) /* OP_CLOSURE */
,opmode(0, 1, OpArgU, OpArgN, iABC) /* OP_VARARG */
+ ,opmode(0, 0, OpArgU, OpArgU, iAx) /* OP_EXTRAARG */
};
diff --git a/l2detect/lua/lopcodes.h b/l2detect/lua/lopcodes.h
index 41224d6..07d2b3f 100644
--- a/l2detect/lua/lopcodes.h
+++ b/l2detect/lua/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.125.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -17,6 +17,7 @@
`A' : 8 bits
`B' : 9 bits
`C' : 9 bits
+ 'Ax' : 26 bits ('A', 'B', and 'C' together)
`Bx' : 18 bits (`B' and `C' together)
`sBx' : signed Bx
@@ -28,7 +29,7 @@
===========================================================================*/
-enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
+enum OpMode {iABC, iABx, iAsBx, iAx}; /* basic instruction format */
/*
@@ -38,6 +39,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
#define SIZE_B 9
#define SIZE_Bx (SIZE_C + SIZE_B)
#define SIZE_A 8
+#define SIZE_Ax (SIZE_C + SIZE_B + SIZE_A)
#define SIZE_OP 6
@@ -46,6 +48,7 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
#define POS_C (POS_A + SIZE_A)
#define POS_B (POS_C + SIZE_C)
#define POS_Bx POS_C
+#define POS_Ax POS_A
/*
@@ -61,6 +64,12 @@ enum OpMode {iABC, iABx, iAsBx}; /* basic instruction format */
#define MAXARG_sBx MAX_INT
#endif
+#if SIZE_Ax < LUAI_BITSINT-1
+#define MAXARG_Ax ((1<>POS_A) & MASK1(SIZE_A,0)))
-#define SETARG_A(i,u) ((i) = (((i)&MASK0(SIZE_A,POS_A)) | \
- ((cast(Instruction, u)<>pos) & MASK1(size,0)))
+#define setarg(i,v,pos,size) ((i) = (((i)&MASK0(size,pos)) | \
+ ((cast(Instruction, v)<>POS_B) & MASK1(SIZE_B,0)))
-#define SETARG_B(i,b) ((i) = (((i)&MASK0(SIZE_B,POS_B)) | \
- ((cast(Instruction, b)<>POS_C) & MASK1(SIZE_C,0)))
-#define SETARG_C(i,b) ((i) = (((i)&MASK0(SIZE_C,POS_C)) | \
- ((cast(Instruction, b)<>POS_Bx) & MASK1(SIZE_Bx,0)))
-#define SETARG_Bx(i,b) ((i) = (((i)&MASK0(SIZE_Bx,POS_Bx)) | \
- ((cast(Instruction, b)<= R(A) + 1 */
OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */
-OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
-OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
+OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */
+OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */
-OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
-OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
+OP_TEST,/* A C if not (R(A) <=> C) then pc++ */
+OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */
OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */
@@ -197,39 +212,44 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2);
if R(A) = R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */
-OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2));
- if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */
+OP_TFORCALL,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); */
+OP_TFORLOOP,/* A sBx if R(A+1) ~= nil then { R(A)=R(A+1); pc += sBx }*/
+
OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */
-OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/
-OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n)) */
+OP_CLOSURE,/* A Bx R(A) := closure(KPROTO[Bx]) */
-OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
+OP_VARARG,/* A B R(A), R(A+1), ..., R(A+B-2) = vararg */
+
+OP_EXTRAARG/* Ax extra (larger) argument for previous opcode */
} OpCode;
-#define NUM_OPCODES (cast(int, OP_VARARG) + 1)
+#define NUM_OPCODES (cast(int, OP_EXTRAARG) + 1)
/*===========================================================================
Notes:
- (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
- and can be 0: OP_CALL then sets `top' to last_result+1, so
- next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.
+ (*) In OP_CALL, if (B == 0) then B = top. If (C == 0), then `top' is
+ set to last_result+1, so next open instruction (OP_CALL, OP_RETURN,
+ OP_SETLIST) may use `top'.
(*) In OP_VARARG, if (B == 0) then use actual number of varargs and
- set top (like in OP_CALL with C == 0).
+ set top (like in OP_CALL with C == 0).
- (*) In OP_RETURN, if (B == 0) then return up to `top'
+ (*) In OP_RETURN, if (B == 0) then return up to `top'.
- (*) In OP_SETLIST, if (B == 0) then B = `top';
- if (C == 0) then next `instruction' is real C
+ (*) In OP_SETLIST, if (B == 0) then B = `top'; if (C == 0) then next
+ 'instruction' is EXTRAARG(real C).
+
+ (*) In OP_LOADKX, the next 'instruction' is always EXTRAARG.
(*) For comparisons, A specifies what condition the test should accept
- (true or false).
+ (true or false).
+
+ (*) All `skips' (pc++) assume that next instruction is a jump.
- (*) All `skips' (pc++) assume that next instruction is a jump
===========================================================================*/
@@ -239,8 +259,8 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
-** bit 7: operator is a test
-*/
+** bit 7: operator is a test (next instruction must be a jump)
+*/
enum OpArgMask {
OpArgN, /* argument is not used */
@@ -249,7 +269,7 @@ enum OpArgMask {
OpArgK /* argument is a constant or register/constant */
};
-LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
+LUAI_DDEC const lu_byte luaP_opmodes[NUM_OPCODES];
#define getOpMode(m) (cast(enum OpMode, luaP_opmodes[m] & 3))
#define getBMode(m) (cast(enum OpArgMask, (luaP_opmodes[m] >> 4) & 3))
@@ -258,7 +278,7 @@ LUAI_DATA const lu_byte luaP_opmodes[NUM_OPCODES];
#define testTMode(m) (luaP_opmodes[m] & (1 << 7))
-LUAI_DATA const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
+LUAI_DDEC const char *const luaP_opnames[NUM_OPCODES+1]; /* opcode names */
/* number of list items to accumulate before a SETLIST instruction */
diff --git a/l2detect/lua/loslib.c b/l2detect/lua/loslib.c
index dc7d145..e51a99a 100644
--- a/l2detect/lua/loslib.c
+++ b/l2detect/lua/loslib.c
@@ -1,16 +1,15 @@
/*
-** $Id: loslib.c,v 1.19.1.3 2008/01/18 16:38:18 roberto Exp $
+** $Id: loslib.c,v 1.38 2011/11/30 12:35:05 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
-
+#include "stdafx.h"
//#include
//#include
//#include
//#include
//#include
-#include "stdafx.h"
#define loslib_c
#define LUA_LIB
@@ -21,37 +20,84 @@
#include "lualib.h"
-static int os_pushresult (lua_State *L, int i, const char *filename) {
- int en = errno; /* calls to Lua API may change this value */
- if (i) {
- lua_pushboolean(L, 1);
- return 1;
- }
- else {
- lua_pushnil(L);
- lua_pushfstring(L, "%s: %s", filename, strerror(en));
- lua_pushinteger(L, en);
- return 3;
- }
-}
+/*
+** list of valid conversion specifiers for the 'strftime' function
+*/
+#if !defined(LUA_STRFTIMEOPTIONS)
+
+#if !defined(LUA_USE_POSIX)
+#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
+#else
+#define LUA_STRFTIMEOPTIONS { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
+ "E", "cCxXyY", \
+ "O", "deHImMSuUVwWy" }
+#endif
+
+#endif
+
+
+
+/*
+** By default, Lua uses tmpnam except when POSIX is available, where it
+** uses mkstemp.
+*/
+#if defined(LUA_USE_MKSTEMP)
+#include
+#define LUA_TMPNAMBUFSIZE 32
+#define lua_tmpnam(b,e) { \
+ strcpy(b, "/tmp/lua_XXXXXX"); \
+ e = mkstemp(b); \
+ if (e != -1) close(e); \
+ e = (e == -1); }
+
+#elif !defined(lua_tmpnam)
+
+#define LUA_TMPNAMBUFSIZE L_tmpnam
+#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
+
+#endif
+
+
+/*
+** By default, Lua uses gmtime/localtime, except when POSIX is available,
+** where it uses gmtime_r/localtime_r
+*/
+#if defined(LUA_USE_GMTIME_R)
+
+#define l_gmtime(t,r) gmtime_r(t,r)
+#define l_localtime(t,r) localtime_r(t,r)
+
+#elif !defined(l_gmtime)
+
+#define l_gmtime(t,r) ((void)r, gmtime(t))
+#define l_localtime(t,r) ((void)r, localtime(t))
+
+#endif
+
static int os_execute (lua_State *L) {
- lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
- return 1;
+ const char *cmd = luaL_optstring(L, 1, NULL);
+ int stat = system(cmd);
+ if (cmd != NULL)
+ return luaL_execresult(L, stat);
+ else {
+ lua_pushboolean(L, stat); /* true if there is a shell */
+ return 1;
+ }
}
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
- return os_pushresult(L, remove(filename) == 0, filename);
+ return luaL_fileresult(L, remove(filename) == 0, filename);
}
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
- return os_pushresult(L, rename(fromname, toname) == 0, fromname);
+ return luaL_fileresult(L, rename(fromname, toname) == 0, fromname);
}
@@ -108,11 +154,10 @@ static int getboolfield (lua_State *L, const char *key) {
static int getfield (lua_State *L, const char *key, int d) {
- int res;
+ int res, isnum;
lua_getfield(L, -1, key);
- if (lua_isnumber(L, -1))
- res = (int)lua_tointeger(L, -1);
- else {
+ res = (int)lua_tointegerx(L, -1, &isnum);
+ if (!isnum) {
if (d < 0)
return luaL_error(L, "field " LUA_QS " missing in date table", key);
res = d;
@@ -122,16 +167,40 @@ static int getfield (lua_State *L, const char *key, int d) {
}
+static const char *checkoption (lua_State *L, const char *conv, char *buff) {
+ static const char *const options[] = LUA_STRFTIMEOPTIONS;
+ unsigned int i;
+ for (i = 0; i < sizeof(options)/sizeof(options[0]); i += 2) {
+ if (*conv != '\0' && strchr(options[i], *conv) != NULL) {
+ buff[1] = *conv;
+ if (*options[i + 1] == '\0') { /* one-char conversion specifier? */
+ buff[2] = '\0'; /* end buffer */
+ return conv + 1;
+ }
+ else if (*(conv + 1) != '\0' &&
+ strchr(options[i + 1], *(conv + 1)) != NULL) {
+ buff[2] = *(conv + 1); /* valid two-char conversion specifier */
+ buff[3] = '\0'; /* end buffer */
+ return conv + 2;
+ }
+ }
+ }
+ luaL_argerror(L, 1,
+ lua_pushfstring(L, "invalid conversion specifier '%%%s'", conv));
+ return conv; /* to avoid warnings */
+}
+
+
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
- struct tm *stm;
+ struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
- stm = gmtime(&t);
+ stm = l_gmtime(&t, &tmr);
s++; /* skip `!' */
}
else
- stm = localtime(&t);
+ stm = l_localtime(&t, &tmr);
if (stm == NULL) /* invalid date? */
lua_pushnil(L);
else if (strcmp(s, "*t") == 0) {
@@ -147,17 +216,17 @@ static int os_date (lua_State *L) {
setboolfield(L, "isdst", stm->tm_isdst);
}
else {
- char cc[3];
+ char cc[4];
luaL_Buffer b;
- cc[0] = '%'; cc[2] = '\0';
+ cc[0] = '%';
luaL_buffinit(L, &b);
- for (; *s; s++) {
- if (*s != '%' || *(s + 1) == '\0') /* no conversion specifier? */
- luaL_addchar(&b, *s);
+ while (*s) {
+ if (*s != '%') /* no conversion specifier? */
+ luaL_addchar(&b, *s++);
else {
size_t reslen;
char buff[200]; /* should be big enough for any conversion result */
- cc[1] = *(++s);
+ s = checkoption(L, s + 1, cc);
reslen = strftime(buff, sizeof(buff), cc, stm);
luaL_addlstring(&b, buff, reslen);
}
@@ -215,9 +284,18 @@ static int os_setlocale (lua_State *L) {
static int os_exit (lua_State *L) {
- exit(luaL_optint(L, 1, EXIT_SUCCESS));
+ int status;
+ if (lua_isboolean(L, 1))
+ status = (lua_toboolean(L, 1) ? EXIT_SUCCESS : EXIT_FAILURE);
+ else
+ status = luaL_optint(L, 1, EXIT_SUCCESS);
+ if (lua_toboolean(L, 2))
+ lua_close(L);
+ if (L) exit(status); /* 'if' to avoid warnings for unreachable 'return' */
+ return 0;
}
+
static const luaL_Reg syslib[] = {
{"clock", os_clock},
{"date", os_date},
@@ -237,8 +315,8 @@ static const luaL_Reg syslib[] = {
-LUALIB_API int luaopen_os (lua_State *L) {
- luaL_register(L, LUA_OSLIBNAME, syslib);
+LUAMOD_API int luaopen_os (lua_State *L) {
+ luaL_newlib(L, syslib);
return 1;
}
diff --git a/l2detect/lua/lparser.c b/l2detect/lua/lparser.c
index d41e879..7453c0a 100644
--- a/l2detect/lua/lparser.c
+++ b/l2detect/lua/lparser.c
@@ -1,12 +1,11 @@
/*
-** $Id: lparser.c,v 2.42.1.3 2007/12/28 15:32:23 roberto Exp $
+** $Id: lparser.c,v 2.124 2011/12/02 13:23:56 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
-
-//#include
#include "stdafx.h"
+//#include
#define lparser_c
#define LUA_CORE
@@ -28,11 +27,13 @@
+/* maximum number of local variables per function (must be smaller
+ than 250, due to the bytecode format) */
+#define MAXVARS 200
+
+
#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
-#define getlocvar(fs, i) ((fs)->f->locvars[(fs)->actvar[i]])
-
-#define luaY_checklimit(fs,v,l,m) if ((v)>(l)) errorlimit(fs,l,m)
/*
@@ -40,10 +41,11 @@
*/
typedef struct BlockCnt {
struct BlockCnt *previous; /* chain */
- int breaklist; /* list of jumps out of this loop */
- lu_byte nactvar; /* # active locals outside the breakable structure */
+ short firstlabel; /* index of first label in this block */
+ short firstgoto; /* index of first pending goto in this block */
+ lu_byte nactvar; /* # active locals outside the block */
lu_byte upval; /* true if some variable in the block is an upvalue */
- lu_byte isbreakable; /* true if `block' is a loop */
+ lu_byte isloop; /* true if `block' is a loop */
} BlockCnt;
@@ -51,11 +53,13 @@ typedef struct BlockCnt {
/*
** prototypes for recursive non-terminal functions
*/
-static void chunk (LexState *ls);
+static void statement (LexState *ls);
static void expr (LexState *ls, expdesc *v);
static void anchor_token (LexState *ls) {
+ /* last token from outer function must be EOS */
+ lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
TString *ts = ls->t.seminfo.ts;
luaX_newstring(ls, getstr(ts), ts->tsv.len);
@@ -63,18 +67,34 @@ static void anchor_token (LexState *ls) {
}
-static void error_expected (LexState *ls, int token) {
- luaX_syntaxerror(ls,
- luaO_pushfstring(ls->L, LUA_QS " expected", luaX_token2str(ls, token)));
+/* semantic error */
+static l_noret semerror (LexState *ls, const char *msg) {
+ ls->t.token = 0; /* remove 'near to' from final message */
+ luaX_syntaxerror(ls, msg);
}
-static void errorlimit (FuncState *fs, int limit, const char *what) {
- const char *msg = (fs->f->linedefined == 0) ?
- luaO_pushfstring(fs->L, "main function has more than %d %s", limit, what) :
- luaO_pushfstring(fs->L, "function at line %d has more than %d %s",
- fs->f->linedefined, limit, what);
- luaX_lexerror(fs->ls, msg, 0);
+static l_noret error_expected (LexState *ls, int token) {
+ luaX_syntaxerror(ls,
+ luaO_pushfstring(ls->L, "%s expected", luaX_token2str(ls, token)));
+}
+
+
+static l_noret errorlimit (FuncState *fs, int limit, const char *what) {
+ lua_State *L = fs->ls->L;
+ const char *msg;
+ int line = fs->f->linedefined;
+ const char *where = (line == 0)
+ ? "main function"
+ : luaO_pushfstring(L, "function at line %d", line);
+ msg = luaO_pushfstring(L, "too many %s (limit is %d) in %s",
+ what, limit, where);
+ luaX_syntaxerror(fs->ls, msg);
+}
+
+
+static void checklimit (FuncState *fs, int v, int l, const char *what) {
+ if (v > l) errorlimit(fs, l, what);
}
@@ -92,6 +112,7 @@ static void check (LexState *ls, int c) {
error_expected(ls, c);
}
+
static void checknext (LexState *ls, int c) {
check(ls, c);
luaX_next(ls);
@@ -108,7 +129,7 @@ static void check_match (LexState *ls, int what, int who, int where) {
error_expected(ls, what);
else {
luaX_syntaxerror(ls, luaO_pushfstring(ls->L,
- LUA_QS " expected (to close " LUA_QS " at line %d)",
+ "%s expected (to close %s at line %d)",
luaX_token2str(ls, what), luaX_token2str(ls, who), where));
}
}
@@ -127,7 +148,7 @@ static TString *str_checkname (LexState *ls) {
static void init_exp (expdesc *e, expkind k, int i) {
e->f = e->t = NO_JUMP;
e->k = k;
- e->u.s.info = i;
+ e->u.info = i;
}
@@ -136,7 +157,7 @@ static void codestring (LexState *ls, expdesc *e, TString *s) {
}
-static void checkname(LexState *ls, expdesc *e) {
+static void checkname (LexState *ls, expdesc *e) {
codestring(ls, e, str_checkname(ls));
}
@@ -146,7 +167,7 @@ static int registerlocalvar (LexState *ls, TString *varname) {
Proto *f = fs->f;
int oldsize = f->sizelocvars;
luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
- LocVar, SHRT_MAX, "too many local variables");
+ LocVar, SHRT_MAX, "local variables");
while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
f->locvars[fs->nlocvars].varname = varname;
luaC_objbarrier(ls->L, f, varname);
@@ -154,14 +175,30 @@ static int registerlocalvar (LexState *ls, TString *varname) {
}
-#define new_localvarliteral(ls,v,n) \
- new_localvar(ls, luaX_newstring(ls, "" v, (sizeof(v)/sizeof(char))-1), n)
-
-
-static void new_localvar (LexState *ls, TString *name, int n) {
+static void new_localvar (LexState *ls, TString *name) {
FuncState *fs = ls->fs;
- luaY_checklimit(fs, fs->nactvar+n+1, LUAI_MAXVARS, "local variables");
- fs->actvar[fs->nactvar+n] = cast(unsigned short, registerlocalvar(ls, name));
+ Dyndata *dyd = ls->dyd;
+ int reg = registerlocalvar(ls, name);
+ checklimit(fs, dyd->actvar.n + 1 - fs->firstlocal,
+ MAXVARS, "local variables");
+ luaM_growvector(ls->L, dyd->actvar.arr, dyd->actvar.n + 1,
+ dyd->actvar.size, Vardesc, MAX_INT, "local variables");
+ dyd->actvar.arr[dyd->actvar.n++].idx = cast(short, reg);
+}
+
+
+static void new_localvarliteral_ (LexState *ls, const char *name, size_t sz) {
+ new_localvar(ls, luaX_newstring(ls, name, sz));
+}
+
+#define new_localvarliteral(ls,v) \
+ new_localvarliteral_(ls, "" v, (sizeof(v)/sizeof(char))-1)
+
+
+static LocVar *getlocvar (FuncState *fs, int i) {
+ int idx = fs->ls->dyd->actvar.arr[fs->firstlocal + i].idx;
+ lua_assert(idx < fs->nlocvars);
+ return &fs->f->locvars[idx];
}
@@ -169,77 +206,88 @@ static void adjustlocalvars (LexState *ls, int nvars) {
FuncState *fs = ls->fs;
fs->nactvar = cast_byte(fs->nactvar + nvars);
for (; nvars; nvars--) {
- getlocvar(fs, fs->nactvar - nvars).startpc = fs->pc;
+ getlocvar(fs, fs->nactvar - nvars)->startpc = fs->pc;
}
}
-static void removevars (LexState *ls, int tolevel) {
- FuncState *fs = ls->fs;
+static void removevars (FuncState *fs, int tolevel) {
+ fs->ls->dyd->actvar.n -= (fs->nactvar - tolevel);
while (fs->nactvar > tolevel)
- getlocvar(fs, --fs->nactvar).endpc = fs->pc;
+ getlocvar(fs, --fs->nactvar)->endpc = fs->pc;
}
-static int indexupvalue (FuncState *fs, TString *name, expdesc *v) {
+static int searchupvalue (FuncState *fs, TString *name) {
int i;
+ Upvaldesc *up = fs->f->upvalues;
+ for (i = 0; i < fs->nups; i++) {
+ if (eqstr(up[i].name, name)) return i;
+ }
+ return -1; /* not found */
+}
+
+
+static int newupvalue (FuncState *fs, TString *name, expdesc *v) {
Proto *f = fs->f;
int oldsize = f->sizeupvalues;
- for (i=0; inups; i++) {
- if (fs->upvalues[i].k == v->k && fs->upvalues[i].info == v->u.s.info) {
- lua_assert(f->upvalues[i] == name);
- return i;
- }
- }
- /* new one */
- luaY_checklimit(fs, f->nups + 1, LUAI_MAXUPVALUES, "upvalues");
- luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
- TString *, MAX_INT, "");
- while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
- f->upvalues[f->nups] = name;
- luaC_objbarrier(fs->L, f, name);
- lua_assert(v->k == VLOCAL || v->k == VUPVAL);
- fs->upvalues[f->nups].k = cast_byte(v->k);
- fs->upvalues[f->nups].info = cast_byte(v->u.s.info);
- return f->nups++;
+ checklimit(fs, fs->nups + 1, MAXUPVAL, "upvalues");
+ luaM_growvector(fs->ls->L, f->upvalues, fs->nups, f->sizeupvalues,
+ Upvaldesc, MAXUPVAL, "upvalues");
+ while (oldsize < f->sizeupvalues) f->upvalues[oldsize++].name = NULL;
+ f->upvalues[fs->nups].instack = (v->k == VLOCAL);
+ f->upvalues[fs->nups].idx = cast_byte(v->u.info);
+ f->upvalues[fs->nups].name = name;
+ luaC_objbarrier(fs->ls->L, f, name);
+ return fs->nups++;
}
static int searchvar (FuncState *fs, TString *n) {
int i;
for (i=fs->nactvar-1; i >= 0; i--) {
- if (n == getlocvar(fs, i).varname)
+ if (eqstr(n, getlocvar(fs, i)->varname))
return i;
}
return -1; /* not found */
}
+/*
+ Mark block where variable at given level was defined
+ (to emit close instructions later).
+*/
static void markupval (FuncState *fs, int level) {
BlockCnt *bl = fs->bl;
- while (bl && bl->nactvar > level) bl = bl->previous;
- if (bl) bl->upval = 1;
+ while (bl->nactvar > level) bl = bl->previous;
+ bl->upval = 1;
}
+/*
+ Find variable with given name 'n'. If it is an upvalue, add this
+ upvalue into all intermediate functions.
+*/
static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
- if (fs == NULL) { /* no more levels? */
- init_exp(var, VGLOBAL, NO_REG); /* default is global variable */
- return VGLOBAL;
- }
+ if (fs == NULL) /* no more levels? */
+ return VVOID; /* default is global */
else {
- int v = searchvar(fs, n); /* look up at current level */
- if (v >= 0) {
- init_exp(var, VLOCAL, v);
+ int v = searchvar(fs, n); /* look up locals at current level */
+ if (v >= 0) { /* found? */
+ init_exp(var, VLOCAL, v); /* variable is local */
if (!base)
markupval(fs, v); /* local will be used as an upval */
return VLOCAL;
}
- else { /* not found at current level; try upper one */
- if (singlevaraux(fs->prev, n, var, 0) == VGLOBAL)
- return VGLOBAL;
- var->u.s.info = indexupvalue(fs, n, var); /* else was LOCAL or UPVAL */
- var->k = VUPVAL; /* upvalue in this level */
+ else { /* not found as local at current level; try upvalues */
+ int idx = searchupvalue(fs, n); /* try existing upvalues */
+ if (idx < 0) { /* not found? */
+ if (singlevaraux(fs->prev, n, var, 0) == VVOID) /* try upper levels */
+ return VVOID; /* not found; is a global */
+ /* else was LOCAL or UPVAL */
+ idx = newupvalue(fs, n, var); /* will be a new upvalue */
+ }
+ init_exp(var, VUPVAL, idx);
return VUPVAL;
}
}
@@ -249,8 +297,13 @@ static int singlevaraux (FuncState *fs, TString *n, expdesc *var, int base) {
static void singlevar (LexState *ls, expdesc *var) {
TString *varname = str_checkname(ls);
FuncState *fs = ls->fs;
- if (singlevaraux(fs, varname, var, 1) == VGLOBAL)
- var->u.s.info = luaK_stringK(fs, varname); /* info points to global name */
+ if (singlevaraux(fs, varname, var, 1) == VVOID) { /* global name? */
+ expdesc key;
+ singlevaraux(fs, ls->envn, var, 1); /* get environment variable */
+ lua_assert(var->k == VLOCAL || var->k == VUPVAL);
+ codestring(ls, &key, varname); /* key is variable name */
+ luaK_indexed(fs, var, &key); /* env[varname] */
+ }
}
@@ -275,18 +328,118 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) {
static void enterlevel (LexState *ls) {
- if (++ls->L->nCcalls > LUAI_MAXCCALLS)
- luaX_lexerror(ls, "chunk has too many syntax levels", 0);
+ lua_State *L = ls->L;
+ ++L->nCcalls;
+ checklimit(ls->fs, L->nCcalls, LUAI_MAXCCALLS, "C levels");
}
#define leavelevel(ls) ((ls)->L->nCcalls--)
-static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
- bl->breaklist = NO_JUMP;
- bl->isbreakable = isbreakable;
+static void closegoto (LexState *ls, int g, Labeldesc *label) {
+ int i;
+ FuncState *fs = ls->fs;
+ Labellist *gl = &ls->dyd->gt;
+ Labeldesc *gt = &gl->arr[g];
+ lua_assert(eqstr(gt->name, label->name));
+ if (gt->nactvar < label->nactvar) {
+ TString *vname = getlocvar(fs, gt->nactvar)->varname;
+ const char *msg = luaO_pushfstring(ls->L,
+ " at line %d jumps into the scope of local " LUA_QS,
+ getstr(gt->name), gt->line, getstr(vname));
+ semerror(ls, msg);
+ }
+ luaK_patchlist(fs, gt->pc, label->pc);
+ /* remove goto from pending list */
+ for (i = g; i < gl->n - 1; i++)
+ gl->arr[i] = gl->arr[i + 1];
+ gl->n--;
+}
+
+
+/*
+** try to close a goto with existing labels; this solves backward jumps
+*/
+static int findlabel (LexState *ls, int g) {
+ int i;
+ BlockCnt *bl = ls->fs->bl;
+ Dyndata *dyd = ls->dyd;
+ Labeldesc *gt = &dyd->gt.arr[g];
+ /* check labels in current block for a match */
+ for (i = bl->firstlabel; i < dyd->label.n; i++) {
+ Labeldesc *lb = &dyd->label.arr[i];
+ if (eqstr(lb->name, gt->name)) { /* correct label? */
+ if (gt->nactvar > lb->nactvar &&
+ (bl->upval || dyd->label.n > bl->firstlabel))
+ luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
+ closegoto(ls, g, lb); /* close it */
+ return 1;
+ }
+ }
+ return 0; /* label not found; cannot close goto */
+}
+
+
+static int newlabelentry (LexState *ls, Labellist *l, TString *name,
+ int line, int pc) {
+ int n = l->n;
+ luaM_growvector(ls->L, l->arr, n, l->size,
+ Labeldesc, SHRT_MAX, "labels/gotos");
+ l->arr[n].name = name;
+ l->arr[n].line = line;
+ l->arr[n].nactvar = ls->fs->nactvar;
+ l->arr[n].pc = pc;
+ l->n++;
+ return n;
+}
+
+
+/*
+** check whether new label 'lb' matches any pending gotos in current
+** block; solves forward jumps
+*/
+static void findgotos (LexState *ls, Labeldesc *lb) {
+ Labellist *gl = &ls->dyd->gt;
+ int i = ls->fs->bl->firstgoto;
+ while (i < gl->n) {
+ if (eqstr(gl->arr[i].name, lb->name))
+ closegoto(ls, i, lb);
+ else
+ i++;
+ }
+}
+
+
+/*
+** "export" pending gotos to outer level, to check them against
+** outer labels; if the block being exited has upvalues, and
+** the goto exits the scope of any variable (which can be the
+** upvalue), close those variables being exited.
+*/
+static void movegotosout (FuncState *fs, BlockCnt *bl) {
+ int i = bl->firstgoto;
+ Labellist *gl = &fs->ls->dyd->gt;
+ /* correct pending gotos to current block and try to close it
+ with visible labels */
+ while (i < gl->n) {
+ Labeldesc *gt = &gl->arr[i];
+ if (gt->nactvar > bl->nactvar) {
+ if (bl->upval)
+ luaK_patchclose(fs, gt->pc, bl->nactvar);
+ gt->nactvar = bl->nactvar;
+ }
+ if (!findlabel(fs->ls, i))
+ i++; /* move to next one */
+ }
+}
+
+
+static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isloop) {
+ bl->isloop = isloop;
bl->nactvar = fs->nactvar;
+ bl->firstlabel = fs->ls->dyd->label.n;
+ bl->firstgoto = fs->ls->dyd->gt.n;
bl->upval = 0;
bl->previous = fs->bl;
fs->bl = bl;
@@ -294,63 +447,100 @@ static void enterblock (FuncState *fs, BlockCnt *bl, lu_byte isbreakable) {
}
+/*
+** create a label named "break" to resolve break statements
+*/
+static void breaklabel (LexState *ls) {
+ TString *n = luaS_new(ls->L, "break");
+ int l = newlabelentry(ls, &ls->dyd->label, n, 0, ls->fs->pc);
+ findgotos(ls, &ls->dyd->label.arr[l]);
+}
+
+/*
+** generates an error for an undefined 'goto'; choose appropriate
+** message when label name is a reserved word (which can only be 'break')
+*/
+static l_noret undefgoto (LexState *ls, Labeldesc *gt) {
+ const char *msg = (gt->name->tsv.reserved > 0)
+ ? "<%s> at line %d not inside a loop"
+ : "no visible label " LUA_QS " for at line %d";
+ msg = luaO_pushfstring(ls->L, msg, getstr(gt->name), gt->line);
+ semerror(ls, msg);
+}
+
+
static void leaveblock (FuncState *fs) {
BlockCnt *bl = fs->bl;
+ LexState *ls = fs->ls;
+ if (bl->previous && bl->upval) {
+ /* create a 'jump to here' to close upvalues */
+ int j = luaK_jump(fs);
+ luaK_patchclose(fs, j, bl->nactvar);
+ luaK_patchtohere(fs, j);
+ }
+ if (bl->isloop)
+ breaklabel(ls); /* close pending breaks */
fs->bl = bl->previous;
- removevars(fs->ls, bl->nactvar);
- if (bl->upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- /* a block either controls scope or breaks (never both) */
- lua_assert(!bl->isbreakable || !bl->upval);
+ removevars(fs, bl->nactvar);
lua_assert(bl->nactvar == fs->nactvar);
fs->freereg = fs->nactvar; /* free registers */
- luaK_patchtohere(fs, bl->breaklist);
+ ls->dyd->label.n = bl->firstlabel; /* remove local labels */
+ if (bl->previous) /* inner block? */
+ movegotosout(fs, bl); /* update pending gotos to outer block */
+ else if (bl->firstgoto < ls->dyd->gt.n) /* pending gotos in outer block? */
+ undefgoto(ls, &ls->dyd->gt.arr[bl->firstgoto]); /* error */
}
-static void pushclosure (LexState *ls, FuncState *func, expdesc *v) {
- FuncState *fs = ls->fs;
- Proto *f = fs->f;
- int oldsize = f->sizep;
- int i;
- luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
- MAXARG_Bx, "constant table overflow");
- while (oldsize < f->sizep) f->p[oldsize++] = NULL;
- f->p[fs->np++] = func->f;
- luaC_objbarrier(ls->L, f, func->f);
- init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
- for (i=0; if->nups; i++) {
- OpCode o = (func->upvalues[i].k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
- luaK_codeABC(fs, o, 0, func->upvalues[i].info, 0);
+/*
+** adds prototype being created into its parent list of prototypes
+** and codes instruction to create new closure
+*/
+static void codeclosure (LexState *ls, Proto *clp, expdesc *v) {
+ FuncState *fs = ls->fs->prev;
+ Proto *f = fs->f; /* prototype of function creating new closure */
+ if (fs->np >= f->sizep) {
+ int oldsize = f->sizep;
+ luaM_growvector(ls->L, f->p, fs->np, f->sizep, Proto *,
+ MAXARG_Bx, "functions");
+ while (oldsize < f->sizep) f->p[oldsize++] = NULL;
}
+ f->p[fs->np++] = clp;
+ luaC_objbarrier(ls->L, f, clp);
+ init_exp(v, VRELOCABLE, luaK_codeABx(fs, OP_CLOSURE, 0, fs->np-1));
+ luaK_exp2nextreg(fs, v); /* fix it at stack top (for GC) */
}
-static void open_func (LexState *ls, FuncState *fs) {
+static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
lua_State *L = ls->L;
- Proto *f = luaF_newproto(L);
- fs->f = f;
+ Proto *f;
fs->prev = ls->fs; /* linked list of funcstates */
fs->ls = ls;
- fs->L = L;
ls->fs = fs;
fs->pc = 0;
- fs->lasttarget = -1;
+ fs->lasttarget = 0;
fs->jpc = NO_JUMP;
fs->freereg = 0;
fs->nk = 0;
fs->np = 0;
+ fs->nups = 0;
fs->nlocvars = 0;
fs->nactvar = 0;
+ fs->firstlocal = ls->dyd->actvar.n;
fs->bl = NULL;
+ f = luaF_newproto(L);
+ fs->f = f;
f->source = ls->source;
f->maxstacksize = 2; /* registers 0/1 are always valid */
- fs->h = luaH_new(L, 0, 0);
- /* anchor table of constants and prototype (to avoid being collected) */
- sethvalue2s(L, L->top, fs->h);
- incr_top(L);
+ /* anchor prototype (to avoid being collected) */
setptvalue2s(L, L->top, f);
incr_top(L);
+ fs->h = luaH_new(L);
+ /* anchor table of constants (to avoid being collected) */
+ sethvalue2s(L, L->top, fs->h);
+ incr_top(L);
+ enterblock(fs, bl, 0);
}
@@ -358,8 +548,8 @@ static void close_func (LexState *ls) {
lua_State *L = ls->L;
FuncState *fs = ls->fs;
Proto *f = fs->f;
- removevars(ls, 0);
luaK_ret(fs, 0, 0); /* final return */
+ leaveblock(fs);
luaM_reallocvector(L, f->code, f->sizecode, fs->pc, Instruction);
f->sizecode = fs->pc;
luaM_reallocvector(L, f->lineinfo, f->sizelineinfo, fs->pc, int);
@@ -370,32 +560,28 @@ static void close_func (LexState *ls) {
f->sizep = fs->np;
luaM_reallocvector(L, f->locvars, f->sizelocvars, fs->nlocvars, LocVar);
f->sizelocvars = fs->nlocvars;
- luaM_reallocvector(L, f->upvalues, f->sizeupvalues, f->nups, TString *);
- f->sizeupvalues = f->nups;
- lua_assert(luaG_checkcode(f));
+ luaM_reallocvector(L, f->upvalues, f->sizeupvalues, fs->nups, Upvaldesc);
+ f->sizeupvalues = fs->nups;
lua_assert(fs->bl == NULL);
ls->fs = fs->prev;
- L->top -= 2; /* remove table and prototype from the stack */
- /* last token read was anchored in defunct function; must reanchor it */
- if (fs) anchor_token(ls);
+ /* last token read was anchored in defunct function; must re-anchor it */
+ anchor_token(ls);
+ L->top--; /* pop table of constants */
+ luaC_checkGC(L);
+ L->top--; /* pop prototype (after possible collection) */
}
-Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
- struct LexState lexstate;
- struct FuncState funcstate;
- lexstate.buff = buff;
- luaX_setinput(L, &lexstate, z, luaS_new(L, name));
- open_func(&lexstate, &funcstate);
- funcstate.f->is_vararg = VARARG_ISVARARG; /* main func. is always vararg */
- luaX_next(&lexstate); /* read first token */
- chunk(&lexstate);
- check(&lexstate, TK_EOS);
- close_func(&lexstate);
- lua_assert(funcstate.prev == NULL);
- lua_assert(funcstate.f->nups == 0);
- lua_assert(lexstate.fs == NULL);
- return funcstate.f;
+/*
+** opens the main function, which is a regular vararg function with an
+** upvalue named LUA_ENV
+*/
+static void open_mainfunc (LexState *ls, FuncState *fs, BlockCnt *bl) {
+ expdesc v;
+ open_func(ls, fs, bl);
+ fs->f->is_vararg = 1; /* main function is always vararg */
+ init_exp(&v, VLOCAL, 0);
+ newupvalue(fs, ls->envn, &v); /* create environment upvalue */
}
@@ -405,11 +591,39 @@ Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, const char *name) {
/*============================================================*/
-static void field (LexState *ls, expdesc *v) {
- /* field -> ['.' | ':'] NAME */
+/*
+** check whether current token is in the follow set of a block.
+** 'until' closes syntactical blocks, but do not close scope,
+** so it handled in separate.
+*/
+static int block_follow (LexState *ls, int withuntil) {
+ switch (ls->t.token) {
+ case TK_ELSE: case TK_ELSEIF:
+ case TK_END: case TK_EOS:
+ return 1;
+ case TK_UNTIL: return withuntil;
+ default: return 0;
+ }
+}
+
+
+static void statlist (LexState *ls) {
+ /* statlist -> { stat [`;'] } */
+ while (!block_follow(ls, 1)) {
+ if (ls->t.token == TK_RETURN) {
+ statement(ls);
+ return; /* 'return' must be last statement */
+ }
+ statement(ls);
+ }
+}
+
+
+static void fieldsel (LexState *ls, expdesc *v) {
+ /* fieldsel -> ['.' | ':'] NAME */
FuncState *fs = ls->fs;
expdesc key;
- luaK_exp2anyreg(fs, v);
+ luaK_exp2anyregup(fs, v);
luaX_next(ls); /* skip the dot or colon */
checkname(ls, &key);
luaK_indexed(fs, v, &key);
@@ -448,7 +662,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
expdesc key, val;
int rkkey;
if (ls->t.token == TK_NAME) {
- luaY_checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
+ checklimit(fs, cc->nh, MAX_INT, "items in a constructor");
checkname(ls, &key);
}
else /* ls->t.token == '[' */
@@ -457,7 +671,7 @@ static void recfield (LexState *ls, struct ConsControl *cc) {
checknext(ls, '=');
rkkey = luaK_exp2RK(fs, &key);
expr(ls, &val);
- luaK_codeABC(fs, OP_SETTABLE, cc->t->u.s.info, rkkey, luaK_exp2RK(fs, &val));
+ luaK_codeABC(fs, OP_SETTABLE, cc->t->u.info, rkkey, luaK_exp2RK(fs, &val));
fs->freereg = reg; /* free registers */
}
@@ -467,7 +681,7 @@ static void closelistfield (FuncState *fs, struct ConsControl *cc) {
luaK_exp2nextreg(fs, &cc->v);
cc->v.k = VVOID;
if (cc->tostore == LFIELDS_PER_FLUSH) {
- luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore); /* flush */
+ luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore); /* flush */
cc->tostore = 0; /* no more items pending */
}
}
@@ -477,27 +691,51 @@ static void lastlistfield (FuncState *fs, struct ConsControl *cc) {
if (cc->tostore == 0) return;
if (hasmultret(cc->v.k)) {
luaK_setmultret(fs, &cc->v);
- luaK_setlist(fs, cc->t->u.s.info, cc->na, LUA_MULTRET);
+ luaK_setlist(fs, cc->t->u.info, cc->na, LUA_MULTRET);
cc->na--; /* do not count last expression (unknown number of elements) */
}
else {
if (cc->v.k != VVOID)
luaK_exp2nextreg(fs, &cc->v);
- luaK_setlist(fs, cc->t->u.s.info, cc->na, cc->tostore);
+ luaK_setlist(fs, cc->t->u.info, cc->na, cc->tostore);
}
}
static void listfield (LexState *ls, struct ConsControl *cc) {
+ /* listfield -> exp */
expr(ls, &cc->v);
- luaY_checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
+ checklimit(ls->fs, cc->na, MAX_INT, "items in a constructor");
cc->na++;
cc->tostore++;
}
+static void field (LexState *ls, struct ConsControl *cc) {
+ /* field -> listfield | recfield */
+ switch(ls->t.token) {
+ case TK_NAME: { /* may be 'listfield' or 'recfield' */
+ if (luaX_lookahead(ls) != '=') /* expression? */
+ listfield(ls, cc);
+ else
+ recfield(ls, cc);
+ break;
+ }
+ case '[': {
+ recfield(ls, cc);
+ break;
+ }
+ default: {
+ listfield(ls, cc);
+ break;
+ }
+ }
+}
+
+
static void constructor (LexState *ls, expdesc *t) {
- /* constructor -> ?? */
+ /* constructor -> '{' [ field { sep field } [sep] ] '}'
+ sep -> ',' | ';' */
FuncState *fs = ls->fs;
int line = ls->linenumber;
int pc = luaK_codeABC(fs, OP_NEWTABLE, 0, 0, 0);
@@ -506,30 +744,13 @@ static void constructor (LexState *ls, expdesc *t) {
cc.t = t;
init_exp(t, VRELOCABLE, pc);
init_exp(&cc.v, VVOID, 0); /* no value (yet) */
- luaK_exp2nextreg(ls->fs, t); /* fix it at stack top (for gc) */
+ luaK_exp2nextreg(ls->fs, t); /* fix it at stack top */
checknext(ls, '{');
do {
lua_assert(cc.v.k == VVOID || cc.tostore > 0);
if (ls->t.token == '}') break;
closelistfield(fs, &cc);
- switch(ls->t.token) {
- case TK_NAME: { /* may be listfields or recfields */
- luaX_lookahead(ls);
- if (ls->lookahead.token != '=') /* expression? */
- listfield(ls, &cc);
- else
- recfield(ls, &cc);
- break;
- }
- case '[': { /* constructor_item -> recfield */
- recfield(ls, &cc);
- break;
- }
- default: { /* constructor_part -> listfield */
- listfield(ls, &cc);
- break;
- }
- }
+ field(ls, &cc);
} while (testnext(ls, ',') || testnext(ls, ';'));
check_match(ls, '}', '{', line);
lastlistfield(fs, &cc);
@@ -551,17 +772,13 @@ static void parlist (LexState *ls) {
do {
switch (ls->t.token) {
case TK_NAME: { /* param -> NAME */
- new_localvar(ls, str_checkname(ls), nparams++);
+ new_localvar(ls, str_checkname(ls));
+ nparams++;
break;
}
case TK_DOTS: { /* param -> `...' */
luaX_next(ls);
-#if defined(LUA_COMPAT_VARARG)
- /* use `arg' as default name */
- new_localvarliteral(ls, "arg", nparams++);
- f->is_vararg = VARARG_HASARG | VARARG_NEEDSARG;
-#endif
- f->is_vararg |= VARARG_ISVARARG;
+ f->is_vararg = 1;
break;
}
default: luaX_syntaxerror(ls, " or " LUA_QL("...") " expected");
@@ -569,33 +786,34 @@ static void parlist (LexState *ls) {
} while (!f->is_vararg && testnext(ls, ','));
}
adjustlocalvars(ls, nparams);
- f->numparams = cast_byte(fs->nactvar - (f->is_vararg & VARARG_HASARG));
+ f->numparams = cast_byte(fs->nactvar);
luaK_reserveregs(fs, fs->nactvar); /* reserve register for parameters */
}
-static void body (LexState *ls, expdesc *e, int needself, int line) {
- /* body -> `(' parlist `)' chunk END */
+static void body (LexState *ls, expdesc *e, int ismethod, int line) {
+ /* body -> `(' parlist `)' block END */
FuncState new_fs;
- open_func(ls, &new_fs);
+ BlockCnt bl;
+ open_func(ls, &new_fs, &bl);
new_fs.f->linedefined = line;
checknext(ls, '(');
- if (needself) {
- new_localvarliteral(ls, "self", 0);
+ if (ismethod) {
+ new_localvarliteral(ls, "self"); /* create 'self' parameter */
adjustlocalvars(ls, 1);
}
parlist(ls);
checknext(ls, ')');
- chunk(ls);
+ statlist(ls);
new_fs.f->lastlinedefined = ls->linenumber;
check_match(ls, TK_END, TK_FUNCTION, line);
+ codeclosure(ls, new_fs.f, e);
close_func(ls);
- pushclosure(ls, &new_fs, e);
}
-static int explist1 (LexState *ls, expdesc *v) {
- /* explist1 -> expr { `,' expr } */
+static int explist (LexState *ls, expdesc *v) {
+ /* explist -> expr { `,' expr } */
int n = 1; /* at least one expression */
expr(ls, v);
while (testnext(ls, ',')) {
@@ -607,20 +825,17 @@ static int explist1 (LexState *ls, expdesc *v) {
}
-static void funcargs (LexState *ls, expdesc *f) {
+static void funcargs (LexState *ls, expdesc *f, int line) {
FuncState *fs = ls->fs;
expdesc args;
int base, nparams;
- int line = ls->linenumber;
switch (ls->t.token) {
- case '(': { /* funcargs -> `(' [ explist1 ] `)' */
- if (line != ls->lastline)
- luaX_syntaxerror(ls,"ambiguous syntax (function call x new statement)");
+ case '(': { /* funcargs -> `(' [ explist ] `)' */
luaX_next(ls);
if (ls->t.token == ')') /* arg list is empty? */
args.k = VVOID;
else {
- explist1(ls, &args);
+ explist(ls, &args);
luaK_setmultret(fs, &args);
}
check_match(ls, ')', '(', line);
@@ -637,11 +852,10 @@ static void funcargs (LexState *ls, expdesc *f) {
}
default: {
luaX_syntaxerror(ls, "function arguments expected");
- return;
}
}
lua_assert(f->k == VNONRELOC);
- base = f->u.s.info; /* base register for call */
+ base = f->u.info; /* base register for call */
if (hasmultret(args.k))
nparams = LUA_MULTRET; /* open call */
else {
@@ -682,7 +896,6 @@ static void prefixexp (LexState *ls, expdesc *v) {
}
default: {
luaX_syntaxerror(ls, "unexpected symbol");
- return;
}
}
}
@@ -692,16 +905,17 @@ static void primaryexp (LexState *ls, expdesc *v) {
/* primaryexp ->
prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
FuncState *fs = ls->fs;
+ int line = ls->linenumber;
prefixexp(ls, v);
for (;;) {
switch (ls->t.token) {
- case '.': { /* field */
- field(ls, v);
+ case '.': { /* fieldsel */
+ fieldsel(ls, v);
break;
}
case '[': { /* `[' exp1 `]' */
expdesc key;
- luaK_exp2anyreg(fs, v);
+ luaK_exp2anyregup(fs, v);
yindex(ls, &key);
luaK_indexed(fs, v, &key);
break;
@@ -711,12 +925,12 @@ static void primaryexp (LexState *ls, expdesc *v) {
luaX_next(ls);
checkname(ls, &key);
luaK_self(fs, v, &key);
- funcargs(ls, v);
+ funcargs(ls, v, line);
break;
}
case '(': case TK_STRING: case '{': { /* funcargs */
luaK_exp2nextreg(fs, v);
- funcargs(ls, v);
+ funcargs(ls, v, line);
break;
}
default: return;
@@ -726,7 +940,7 @@ static void primaryexp (LexState *ls, expdesc *v) {
static void simpleexp (LexState *ls, expdesc *v) {
- /* simpleexp -> NUMBER | STRING | NIL | true | false | ... |
+ /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
constructor | FUNCTION body | primaryexp */
switch (ls->t.token) {
case TK_NUMBER: {
@@ -754,7 +968,6 @@ static void simpleexp (LexState *ls, expdesc *v) {
FuncState *fs = ls->fs;
check_condition(ls, fs->f->is_vararg,
"cannot use " LUA_QL("...") " outside a vararg function");
- fs->f->is_vararg &= ~VARARG_NEEDSARG; /* don't need 'arg' */
init_exp(v, VVARARG, luaK_codeABC(fs, OP_VARARG, 0, 1, 0));
break;
}
@@ -812,11 +1025,11 @@ static const struct {
lu_byte left; /* left priority for each binary operator */
lu_byte right; /* right priority */
} priority[] = { /* ORDER OPR */
- {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `/' `%' */
- {10, 9}, {5, 4}, /* power and concat (right associative) */
- {3, 3}, {3, 3}, /* equality and inequality */
- {3, 3}, {3, 3}, {3, 3}, {3, 3}, /* order */
- {2, 2}, {1, 1} /* logical (and/or) */
+ {6, 6}, {6, 6}, {7, 7}, {7, 7}, {7, 7}, /* `+' `-' `*' `/' `%' */
+ {10, 9}, {5, 4}, /* ^, .. (right associative) */
+ {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
+ {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
+ {2, 2}, {1, 1} /* and, or */
};
#define UNARY_PRIORITY 8 /* priority for unary operators */
@@ -826,15 +1039,16 @@ static const struct {
** subexpr -> (simpleexp | unop subexpr) { binop subexpr }
** where `binop' is any binary operator with a priority higher than `limit'
*/
-static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
+static BinOpr subexpr (LexState *ls, expdesc *v, int limit) {
BinOpr op;
UnOpr uop;
enterlevel(ls);
uop = getunopr(ls->t.token);
if (uop != OPR_NOUNOPR) {
+ int line = ls->linenumber;
luaX_next(ls);
subexpr(ls, v, UNARY_PRIORITY);
- luaK_prefix(ls->fs, uop, v);
+ luaK_prefix(ls->fs, uop, v, line);
}
else simpleexp(ls, v);
/* expand while operators have priorities higher than `limit' */
@@ -842,11 +1056,12 @@ static BinOpr subexpr (LexState *ls, expdesc *v, unsigned int limit) {
while (op != OPR_NOBINOPR && priority[op].left > limit) {
expdesc v2;
BinOpr nextop;
+ int line = ls->linenumber;
luaX_next(ls);
luaK_infix(ls->fs, op, v);
/* read sub-expression with higher priority */
nextop = subexpr(ls, &v2, priority[op].right);
- luaK_posfix(ls->fs, op, v, &v2);
+ luaK_posfix(ls->fs, op, v, &v2, line);
op = nextop;
}
leavelevel(ls);
@@ -869,23 +1084,12 @@ static void expr (LexState *ls, expdesc *v) {
*/
-static int block_follow (int token) {
- switch (token) {
- case TK_ELSE: case TK_ELSEIF: case TK_END:
- case TK_UNTIL: case TK_EOS:
- return 1;
- default: return 0;
- }
-}
-
-
static void block (LexState *ls) {
- /* block -> chunk */
+ /* block -> statlist */
FuncState *fs = ls->fs;
BlockCnt bl;
enterblock(fs, &bl, 0);
- chunk(ls);
- lua_assert(bl.breaklist == NO_JUMP);
+ statlist(ls);
leaveblock(fs);
}
@@ -901,29 +1105,34 @@ struct LHS_assign {
/*
-** check whether, in an assignment to a local variable, the local variable
-** is needed in a previous assignment (to a table). If so, save original
-** local value in a safe place and use this safe copy in the previous
-** assignment.
+** check whether, in an assignment to an upvalue/local variable, the
+** upvalue/local variable is begin used in a previous assignment to a
+** table. If so, save original upvalue/local value in a safe place and
+** use this safe copy in the previous assignment.
*/
static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
FuncState *fs = ls->fs;
int extra = fs->freereg; /* eventual position to save local variable */
int conflict = 0;
- for (; lh; lh = lh->prev) {
- if (lh->v.k == VINDEXED) {
- if (lh->v.u.s.info == v->u.s.info) { /* conflict? */
+ for (; lh; lh = lh->prev) { /* check all previous assignments */
+ if (lh->v.k == VINDEXED) { /* assigning to a table? */
+ /* table is the upvalue/local being assigned now? */
+ if (lh->v.u.ind.vt == v->k && lh->v.u.ind.t == v->u.info) {
conflict = 1;
- lh->v.u.s.info = extra; /* previous assignment will use safe copy */
+ lh->v.u.ind.vt = VLOCAL;
+ lh->v.u.ind.t = extra; /* previous assignment will use safe copy */
}
- if (lh->v.u.s.aux == v->u.s.info) { /* conflict? */
+ /* index is the local being assigned? (index cannot be upvalue) */
+ if (v->k == VLOCAL && lh->v.u.ind.idx == v->u.info) {
conflict = 1;
- lh->v.u.s.aux = extra; /* previous assignment will use safe copy */
+ lh->v.u.ind.idx = extra; /* previous assignment will use safe copy */
}
}
}
if (conflict) {
- luaK_codeABC(fs, OP_MOVE, fs->freereg, v->u.s.info, 0); /* make copy */
+ /* copy upvalue/local value to a temporary (in position 'extra') */
+ OpCode op = (v->k == VLOCAL) ? OP_MOVE : OP_GETUPVAL;
+ luaK_codeABC(fs, op, extra, v->u.info, 0);
luaK_reserveregs(fs, 1);
}
}
@@ -931,22 +1140,21 @@ static void check_conflict (LexState *ls, struct LHS_assign *lh, expdesc *v) {
static void assignment (LexState *ls, struct LHS_assign *lh, int nvars) {
expdesc e;
- check_condition(ls, VLOCAL <= lh->v.k && lh->v.k <= VINDEXED,
- "syntax error");
+ check_condition(ls, vkisvar(lh->v.k), "syntax error");
if (testnext(ls, ',')) { /* assignment -> `,' primaryexp assignment */
struct LHS_assign nv;
nv.prev = lh;
primaryexp(ls, &nv.v);
- if (nv.v.k == VLOCAL)
+ if (nv.v.k != VINDEXED)
check_conflict(ls, lh, &nv.v);
- luaY_checklimit(ls->fs, nvars, LUAI_MAXCCALLS - ls->L->nCcalls,
- "variables in assignment");
+ checklimit(ls->fs, nvars + ls->L->nCcalls, LUAI_MAXCCALLS,
+ "C levels");
assignment(ls, &nv, nvars+1);
}
- else { /* assignment -> `=' explist1 */
+ else { /* assignment -> `=' explist */
int nexps;
checknext(ls, '=');
- nexps = explist1(ls, &e);
+ nexps = explist(ls, &e);
if (nexps != nvars) {
adjust_assign(ls, nvars, nexps, &e);
if (nexps > nvars)
@@ -973,19 +1181,52 @@ static int cond (LexState *ls) {
}
-static void breakstat (LexState *ls) {
- FuncState *fs = ls->fs;
- BlockCnt *bl = fs->bl;
- int upval = 0;
- while (bl && !bl->isbreakable) {
- upval |= bl->upval;
- bl = bl->previous;
+static void gotostat (LexState *ls, int pc) {
+ int line = ls->linenumber;
+ TString *label;
+ int g;
+ if (testnext(ls, TK_GOTO))
+ label = str_checkname(ls);
+ else {
+ luaX_next(ls); /* skip break */
+ label = luaS_new(ls->L, "break");
}
- if (!bl)
- luaX_syntaxerror(ls, "no loop to break");
- if (upval)
- luaK_codeABC(fs, OP_CLOSE, bl->nactvar, 0, 0);
- luaK_concat(fs, &bl->breaklist, luaK_jump(fs));
+ g = newlabelentry(ls, &ls->dyd->gt, label, line, pc);
+ findlabel(ls, g); /* close it if label already defined */
+}
+
+
+/* check for repeated labels on the same block */
+static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
+ int i;
+ for (i = fs->bl->firstlabel; i < ll->n; i++) {
+ if (eqstr(label, ll->arr[i].name)) {
+ const char *msg = luaO_pushfstring(fs->ls->L,
+ "label " LUA_QS " already defined on line %d",
+ getstr(label), ll->arr[i].line);
+ semerror(fs->ls, msg);
+ }
+ }
+}
+
+
+static void labelstat (LexState *ls, TString *label, int line) {
+ /* label -> '::' NAME '::' */
+ FuncState *fs = ls->fs;
+ Labellist *ll = &ls->dyd->label;
+ int l; /* index of new label being created */
+ checkrepeated(fs, ll, label); /* check for repeated labels */
+ checknext(ls, TK_DBCOLON); /* skip double colon */
+ /* create new entry for this label */
+ l = newlabelentry(ls, ll, label, line, fs->pc);
+ /* skip other no-op statements */
+ while (ls->t.token == ';' || ls->t.token == TK_DBCOLON)
+ statement(ls);
+ if (block_follow(ls, 0)) { /* label is last no-op statement in the block? */
+ /* assume that locals are already out of scope */
+ ll->arr[l].nactvar = fs->bl->nactvar;
+ }
+ findgotos(ls, &ll->arr[l]);
}
@@ -1001,7 +1242,7 @@ static void whilestat (LexState *ls, int line) {
enterblock(fs, &bl, 1);
checknext(ls, TK_DO);
block(ls);
- luaK_patchlist(fs, luaK_jump(fs), whileinit);
+ luaK_jumpto(fs, whileinit);
check_match(ls, TK_END, TK_WHILE, line);
leaveblock(fs);
luaK_patchtohere(fs, condexit); /* false conditions finish the loop */
@@ -1017,30 +1258,25 @@ static void repeatstat (LexState *ls, int line) {
enterblock(fs, &bl1, 1); /* loop block */
enterblock(fs, &bl2, 0); /* scope block */
luaX_next(ls); /* skip REPEAT */
- chunk(ls);
+ statlist(ls);
check_match(ls, TK_UNTIL, TK_REPEAT, line);
condexit = cond(ls); /* read condition (inside scope block) */
- if (!bl2.upval) { /* no upvalues? */
- leaveblock(fs); /* finish scope */
- luaK_patchlist(ls->fs, condexit, repeat_init); /* close the loop */
- }
- else { /* complete semantics when there are upvalues */
- breakstat(ls); /* if condition then break */
- luaK_patchtohere(ls->fs, condexit); /* else... */
- leaveblock(fs); /* finish scope... */
- luaK_patchlist(ls->fs, luaK_jump(fs), repeat_init); /* and repeat */
- }
+ if (bl2.upval) /* upvalues? */
+ luaK_patchclose(fs, condexit, bl2.nactvar);
+ leaveblock(fs); /* finish scope */
+ luaK_patchlist(fs, condexit, repeat_init); /* close the loop */
leaveblock(fs); /* finish loop */
}
static int exp1 (LexState *ls) {
expdesc e;
- int k;
+ int reg;
expr(ls, &e);
- k = e.k;
luaK_exp2nextreg(ls->fs, &e);
- return k;
+ lua_assert(e.k == VNONRELOC);
+ reg = e.u.info;
+ return reg;
}
@@ -1058,10 +1294,15 @@ static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
block(ls);
leaveblock(fs); /* end of scope for declared variables */
luaK_patchtohere(fs, prep);
- endfor = (isnum) ? luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP) :
- luaK_codeABC(fs, OP_TFORLOOP, base, 0, nvars);
- luaK_fixline(fs, line); /* pretend that `OP_FOR' starts the loop */
- luaK_patchlist(fs, (isnum ? endfor : luaK_jump(fs)), prep + 1);
+ if (isnum) /* numeric for? */
+ endfor = luaK_codeAsBx(fs, OP_FORLOOP, base, NO_JUMP);
+ else { /* generic for */
+ luaK_codeABC(fs, OP_TFORCALL, base, 0, nvars);
+ luaK_fixline(fs, line);
+ endfor = luaK_codeAsBx(fs, OP_TFORLOOP, base + 2, NO_JUMP);
+ }
+ luaK_patchlist(fs, endfor, prep + 1);
+ luaK_fixline(fs, line);
}
@@ -1069,10 +1310,10 @@ static void fornum (LexState *ls, TString *varname, int line) {
/* fornum -> NAME = exp1,exp1[,exp1] forbody */
FuncState *fs = ls->fs;
int base = fs->freereg;
- new_localvarliteral(ls, "(for index)", 0);
- new_localvarliteral(ls, "(for limit)", 1);
- new_localvarliteral(ls, "(for step)", 2);
- new_localvar(ls, varname, 3);
+ new_localvarliteral(ls, "(for index)");
+ new_localvarliteral(ls, "(for limit)");
+ new_localvarliteral(ls, "(for step)");
+ new_localvar(ls, varname);
checknext(ls, '=');
exp1(ls); /* initial value */
checknext(ls, ',');
@@ -1080,7 +1321,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
if (testnext(ls, ','))
exp1(ls); /* optional step */
else { /* default step = 1 */
- luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
+ luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));
luaK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
@@ -1088,23 +1329,25 @@ static void fornum (LexState *ls, TString *varname, int line) {
static void forlist (LexState *ls, TString *indexname) {
- /* forlist -> NAME {,NAME} IN explist1 forbody */
+ /* forlist -> NAME {,NAME} IN explist forbody */
FuncState *fs = ls->fs;
expdesc e;
- int nvars = 0;
+ int nvars = 4; /* gen, state, control, plus at least one declared var */
int line;
int base = fs->freereg;
/* create control variables */
- new_localvarliteral(ls, "(for generator)", nvars++);
- new_localvarliteral(ls, "(for state)", nvars++);
- new_localvarliteral(ls, "(for control)", nvars++);
+ new_localvarliteral(ls, "(for generator)");
+ new_localvarliteral(ls, "(for state)");
+ new_localvarliteral(ls, "(for control)");
/* create declared variables */
- new_localvar(ls, indexname, nvars++);
- while (testnext(ls, ','))
- new_localvar(ls, str_checkname(ls), nvars++);
+ new_localvar(ls, indexname);
+ while (testnext(ls, ',')) {
+ new_localvar(ls, str_checkname(ls));
+ nvars++;
+ }
checknext(ls, TK_IN);
line = ls->linenumber;
- adjust_assign(ls, 3, explist1(ls, &e), &e);
+ adjust_assign(ls, 3, explist(ls, &e), &e);
luaK_checkstack(fs, 3); /* extra space to call generator */
forbody(ls, base, line, nvars - 3, 0);
}
@@ -1128,65 +1371,76 @@ static void forstat (LexState *ls, int line) {
}
-static int test_then_block (LexState *ls) {
+static void test_then_block (LexState *ls, int *escapelist) {
/* test_then_block -> [IF | ELSEIF] cond THEN block */
- int condexit;
+ BlockCnt bl;
+ FuncState *fs = ls->fs;
+ expdesc v;
+ int jf; /* instruction to skip 'then' code (if condition is false) */
luaX_next(ls); /* skip IF or ELSEIF */
- condexit = cond(ls);
+ expr(ls, &v); /* read condition */
checknext(ls, TK_THEN);
- block(ls); /* `then' part */
- return condexit;
+ if (ls->t.token == TK_GOTO || ls->t.token == TK_BREAK) {
+ luaK_goiffalse(ls->fs, &v); /* will jump to label if condition is true */
+ enterblock(fs, &bl, 0); /* must enter block before 'goto' */
+ gotostat(ls, v.t); /* handle goto/break */
+ if (block_follow(ls, 0)) { /* 'goto' is the entire block? */
+ leaveblock(fs);
+ return; /* and that is it */
+ }
+ else /* must skip over 'then' part if condition is false */
+ jf = luaK_jump(fs);
+ }
+ else { /* regular case (not goto/break) */
+ luaK_goiftrue(ls->fs, &v); /* skip over block if condition is false */
+ enterblock(fs, &bl, 0);
+ jf = v.f;
+ }
+ statlist(ls); /* `then' part */
+ leaveblock(fs);
+ if (ls->t.token == TK_ELSE ||
+ ls->t.token == TK_ELSEIF) /* followed by 'else'/'elseif'? */
+ luaK_concat(fs, escapelist, luaK_jump(fs)); /* must jump over it */
+ luaK_patchtohere(fs, jf);
}
static void ifstat (LexState *ls, int line) {
/* ifstat -> IF cond THEN block {ELSEIF cond THEN block} [ELSE block] END */
FuncState *fs = ls->fs;
- int flist;
- int escapelist = NO_JUMP;
- flist = test_then_block(ls); /* IF cond THEN block */
- while (ls->t.token == TK_ELSEIF) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- flist = test_then_block(ls); /* ELSEIF cond THEN block */
- }
- if (ls->t.token == TK_ELSE) {
- luaK_concat(fs, &escapelist, luaK_jump(fs));
- luaK_patchtohere(fs, flist);
- luaX_next(ls); /* skip ELSE (after patch, for correct line info) */
+ int escapelist = NO_JUMP; /* exit list for finished parts */
+ test_then_block(ls, &escapelist); /* IF cond THEN block */
+ while (ls->t.token == TK_ELSEIF)
+ test_then_block(ls, &escapelist); /* ELSEIF cond THEN block */
+ if (testnext(ls, TK_ELSE))
block(ls); /* `else' part */
- }
- else
- luaK_concat(fs, &escapelist, flist);
- luaK_patchtohere(fs, escapelist);
check_match(ls, TK_END, TK_IF, line);
+ luaK_patchtohere(fs, escapelist); /* patch escape list to 'if' end */
}
static void localfunc (LexState *ls) {
- expdesc v, b;
+ expdesc b;
FuncState *fs = ls->fs;
- new_localvar(ls, str_checkname(ls), 0);
- init_exp(&v, VLOCAL, fs->freereg);
- luaK_reserveregs(fs, 1);
- adjustlocalvars(ls, 1);
- body(ls, &b, 0, ls->linenumber);
- luaK_storevar(fs, &v, &b);
+ new_localvar(ls, str_checkname(ls)); /* new local variable */
+ adjustlocalvars(ls, 1); /* enter its scope */
+ body(ls, &b, 0, ls->linenumber); /* function created in next register */
/* debug information will only see the variable after this point! */
- getlocvar(fs, fs->nactvar - 1).startpc = fs->pc;
+ getlocvar(fs, b.u.info)->startpc = fs->pc;
}
static void localstat (LexState *ls) {
- /* stat -> LOCAL NAME {`,' NAME} [`=' explist1] */
+ /* stat -> LOCAL NAME {`,' NAME} [`=' explist] */
int nvars = 0;
int nexps;
expdesc e;
do {
- new_localvar(ls, str_checkname(ls), nvars++);
+ new_localvar(ls, str_checkname(ls));
+ nvars++;
} while (testnext(ls, ','));
if (testnext(ls, '='))
- nexps = explist1(ls, &e);
+ nexps = explist(ls, &e);
else {
e.k = VVOID;
nexps = 0;
@@ -1197,26 +1451,26 @@ static void localstat (LexState *ls) {
static int funcname (LexState *ls, expdesc *v) {
- /* funcname -> NAME {field} [`:' NAME] */
- int needself = 0;
+ /* funcname -> NAME {fieldsel} [`:' NAME] */
+ int ismethod = 0;
singlevar(ls, v);
while (ls->t.token == '.')
- field(ls, v);
+ fieldsel(ls, v);
if (ls->t.token == ':') {
- needself = 1;
- field(ls, v);
+ ismethod = 1;
+ fieldsel(ls, v);
}
- return needself;
+ return ismethod;
}
static void funcstat (LexState *ls, int line) {
/* funcstat -> FUNCTION funcname body */
- int needself;
+ int ismethod;
expdesc v, b;
luaX_next(ls); /* skip FUNCTION */
- needself = funcname(ls, &v);
- body(ls, &b, needself, line);
+ ismethod = funcname(ls, &v);
+ body(ls, &b, ismethod, line);
luaK_storevar(ls->fs, &v, &b);
luaK_fixline(ls->fs, line); /* definition `happens' in the first line */
}
@@ -1237,15 +1491,14 @@ static void exprstat (LexState *ls) {
static void retstat (LexState *ls) {
- /* stat -> RETURN explist */
+ /* stat -> RETURN [explist] [';'] */
FuncState *fs = ls->fs;
expdesc e;
int first, nret; /* registers with returned values */
- luaX_next(ls); /* skip RETURN */
- if (block_follow(ls->t.token) || ls->t.token == ';')
+ if (block_follow(ls, 1) || ls->t.token == ';')
first = nret = 0; /* return no values */
else {
- nret = explist1(ls, &e); /* optional return values */
+ nret = explist(ls, &e); /* optional return values */
if (hasmultret(e.k)) {
luaK_setmultret(fs, &e);
if (e.k == VCALL && nret == 1) { /* tail call? */
@@ -1266,37 +1519,43 @@ static void retstat (LexState *ls) {
}
}
luaK_ret(fs, first, nret);
+ testnext(ls, ';'); /* skip optional semicolon */
}
-static int statement (LexState *ls) {
+static void statement (LexState *ls) {
int line = ls->linenumber; /* may be needed for error messages */
+ enterlevel(ls);
switch (ls->t.token) {
+ case ';': { /* stat -> ';' (empty statement) */
+ luaX_next(ls); /* skip ';' */
+ break;
+ }
case TK_IF: { /* stat -> ifstat */
ifstat(ls, line);
- return 0;
+ break;
}
case TK_WHILE: { /* stat -> whilestat */
whilestat(ls, line);
- return 0;
+ break;
}
case TK_DO: { /* stat -> DO block END */
luaX_next(ls); /* skip DO */
block(ls);
check_match(ls, TK_END, TK_DO, line);
- return 0;
+ break;
}
case TK_FOR: { /* stat -> forstat */
forstat(ls, line);
- return 0;
+ break;
}
case TK_REPEAT: { /* stat -> repeatstat */
repeatstat(ls, line);
- return 0;
+ break;
}
- case TK_FUNCTION: {
- funcstat(ls, line); /* stat -> funcstat */
- return 0;
+ case TK_FUNCTION: { /* stat -> funcstat */
+ funcstat(ls, line);
+ break;
}
case TK_LOCAL: { /* stat -> localstat */
luaX_next(ls); /* skip LOCAL */
@@ -1304,37 +1563,58 @@ static int statement (LexState *ls) {
localfunc(ls);
else
localstat(ls);
- return 0;
+ break;
+ }
+ case TK_DBCOLON: { /* stat -> label */
+ luaX_next(ls); /* skip double colon */
+ labelstat(ls, str_checkname(ls), line);
+ break;
}
case TK_RETURN: { /* stat -> retstat */
+ luaX_next(ls); /* skip RETURN */
retstat(ls);
- return 1; /* must be last statement */
+ break;
}
- case TK_BREAK: { /* stat -> breakstat */
- luaX_next(ls); /* skip BREAK */
- breakstat(ls);
- return 1; /* must be last statement */
+ case TK_BREAK: /* stat -> breakstat */
+ case TK_GOTO: { /* stat -> 'goto' NAME */
+ gotostat(ls, luaK_jump(ls->fs));
+ break;
}
- default: {
+ default: { /* stat -> func | assignment */
exprstat(ls);
- return 0; /* to avoid warnings */
+ break;
}
}
-}
-
-
-static void chunk (LexState *ls) {
- /* chunk -> { stat [`;'] } */
- int islast = 0;
- enterlevel(ls);
- while (!islast && !block_follow(ls->t.token)) {
- islast = statement(ls);
- testnext(ls, ';');
- lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
- ls->fs->freereg >= ls->fs->nactvar);
- ls->fs->freereg = ls->fs->nactvar; /* free registers */
- }
+ lua_assert(ls->fs->f->maxstacksize >= ls->fs->freereg &&
+ ls->fs->freereg >= ls->fs->nactvar);
+ ls->fs->freereg = ls->fs->nactvar; /* free registers */
leavelevel(ls);
}
/* }====================================================================== */
+
+
+Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
+ Dyndata *dyd, const char *name, int firstchar) {
+ LexState lexstate;
+ FuncState funcstate;
+ BlockCnt bl;
+ TString *tname = luaS_new(L, name);
+ setsvalue2s(L, L->top, tname); /* push name to protect it */
+ incr_top(L);
+ lexstate.buff = buff;
+ lexstate.dyd = dyd;
+ dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
+ luaX_setinput(L, &lexstate, z, tname, firstchar);
+ open_mainfunc(&lexstate, &funcstate, &bl);
+ luaX_next(&lexstate); /* read first token */
+ statlist(&lexstate); /* main body */
+ check(&lexstate, TK_EOS);
+ close_func(&lexstate);
+ L->top--; /* pop name */
+ lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
+ /* all scopes should be correctly finished */
+ lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
+ return funcstate.f;
+}
+
diff --git a/l2detect/lua/lparser.h b/l2detect/lua/lparser.h
index 18836af..caabf46 100644
--- a/l2detect/lua/lparser.h
+++ b/l2detect/lua/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.57.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lparser.h,v 1.69 2011/07/27 18:09:01 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -23,34 +23,72 @@ typedef enum {
VFALSE,
VK, /* info = index of constant in `k' */
VKNUM, /* nval = numerical value */
+ VNONRELOC, /* info = result register */
VLOCAL, /* info = local register */
- VUPVAL, /* info = index of upvalue in `upvalues' */
- VGLOBAL, /* info = index of table; aux = index of global name in `k' */
- VINDEXED, /* info = table register; aux = index register (or `k') */
+ VUPVAL, /* info = index of upvalue in 'upvalues' */
+ VINDEXED, /* t = table register/upvalue; idx = index R/K */
VJMP, /* info = instruction pc */
VRELOCABLE, /* info = instruction pc */
- VNONRELOC, /* info = result register */
VCALL, /* info = instruction pc */
VVARARG /* info = instruction pc */
} expkind;
+
+#define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED)
+#define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL)
+
typedef struct expdesc {
expkind k;
union {
- struct { int info, aux; } s;
- lua_Number nval;
+ struct { /* for indexed variables (VINDEXED) */
+ short idx; /* index (R/K) */
+ lu_byte t; /* table (register or upvalue) */
+ lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
+ } ind;
+ int info; /* for generic use */
+ lua_Number nval; /* for VKNUM */
} u;
int t; /* patch list of `exit when true' */
int f; /* patch list of `exit when false' */
} expdesc;
-typedef struct upvaldesc {
- lu_byte k;
- lu_byte info;
-} upvaldesc;
+/* description of active local variable */
+typedef struct Vardesc {
+ short idx; /* variable index in stack */
+} Vardesc;
+/* description of pending goto statements and label statements */
+typedef struct Labeldesc {
+ TString *name; /* label identifier */
+ int pc; /* position in code */
+ int line; /* line where it appeared */
+ lu_byte nactvar; /* local level where it appears in current block */
+} Labeldesc;
+
+
+/* list of labels or gotos */
+typedef struct Labellist {
+ Labeldesc *arr; /* array */
+ int n; /* number of entries in use */
+ int size; /* array size */
+} Labellist;
+
+
+/* dynamic structures used by the parser */
+typedef struct Dyndata {
+ struct { /* list of active local variables */
+ Vardesc *arr;
+ int n;
+ int size;
+ } actvar;
+ Labellist gt; /* list of pending gotos */
+ Labellist label; /* list of active labels */
+} Dyndata;
+
+
+/* control of blocks */
struct BlockCnt; /* defined in lparser.c */
@@ -60,23 +98,22 @@ typedef struct FuncState {
Table *h; /* table to find (and reuse) elements in `k' */
struct FuncState *prev; /* enclosing function */
struct LexState *ls; /* lexical state */
- struct lua_State *L; /* copy of the Lua state */
struct BlockCnt *bl; /* chain of current blocks */
int pc; /* next position to code (equivalent to `ncode') */
- int lasttarget; /* `pc' of last `jump target' */
+ int lasttarget; /* 'label' of last 'jump label' */
int jpc; /* list of pending jumps to `pc' */
- int freereg; /* first free register */
int nk; /* number of elements in `k' */
int np; /* number of elements in `p' */
- short nlocvars; /* number of elements in `locvars' */
+ int firstlocal; /* index of first local var (in Dyndata array) */
+ short nlocvars; /* number of elements in 'f->locvars' */
lu_byte nactvar; /* number of active local variables */
- upvaldesc upvalues[LUAI_MAXUPVALUES]; /* upvalues */
- unsigned short actvar[LUAI_MAXVARS]; /* declared-variable stack */
+ lu_byte nups; /* number of upvalues */
+ lu_byte freereg; /* first free register */
} FuncState;
LUAI_FUNC Proto *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff,
- const char *name);
+ Dyndata *dyd, const char *name, int firstchar);
#endif
diff --git a/l2detect/lua/lstate.c b/l2detect/lua/lstate.c
index e9966f6..d9a52bb 100644
--- a/l2detect/lua/lstate.c
+++ b/l2detect/lua/lstate.c
@@ -1,18 +1,18 @@
/*
-** $Id: lstate.c,v 2.36.1.2 2008/01/03 15:20:39 roberto Exp $
+** $Id: lstate.c,v 2.92 2011/10/03 17:54:25 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
-
-//#include
#include "stdafx.h"
+//#include
#define lstate_c
#define LUA_CORE
#include "lua.h"
+#include "lapi.h"
#include "ldebug.h"
#include "ldo.h"
#include "lfunc.h"
@@ -25,119 +25,203 @@
#include "ltm.h"
-#define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
-#define fromstate(l) (cast(lu_byte *, (l)) - LUAI_EXTRASPACE)
-#define tostate(l) (cast(lua_State *, cast(lu_byte *, l) + LUAI_EXTRASPACE))
+#if !defined(LUAI_GCPAUSE)
+#define LUAI_GCPAUSE 200 /* 200% */
+#endif
+
+#if !defined(LUAI_GCMAJOR)
+#define LUAI_GCMAJOR 200 /* 200% */
+#endif
+
+#if !defined(LUAI_GCMUL)
+#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
+#endif
+
+
+#define MEMERRMSG "not enough memory"
+
+
+/*
+** thread state + extra space
+*/
+typedef struct LX {
+#if defined(LUAI_EXTRASPACE)
+ char buff[LUAI_EXTRASPACE];
+#endif
+ lua_State l;
+} LX;
/*
** Main thread combines a thread state and the global state
*/
typedef struct LG {
- lua_State l;
+ LX l;
global_State g;
} LG;
-
-static void stack_init (lua_State *L1, lua_State *L) {
- /* initialize CallInfo array */
- L1->base_ci = luaM_newvector(L, BASIC_CI_SIZE, CallInfo);
- L1->ci = L1->base_ci;
- L1->size_ci = BASIC_CI_SIZE;
- L1->end_ci = L1->base_ci + L1->size_ci - 1;
- /* initialize stack array */
- L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, TValue);
- L1->stacksize = BASIC_STACK_SIZE + EXTRA_STACK;
- L1->top = L1->stack;
- L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
- /* initialize first ci */
- L1->ci->func = L1->top;
- setnilvalue(L1->top++); /* `function' entry for this `ci' */
- L1->base = L1->ci->base = L1->top;
- L1->ci->top = L1->top + LUA_MINSTACK;
+
+#define fromstate(L) (cast(LX *, cast(lu_byte *, (L)) - offsetof(LX, l)))
+
+
+/*
+** set GCdebt to a new value keeping the value (totalbytes + GCdebt)
+** invariant
+*/
+void luaE_setdebt (global_State *g, l_mem debt) {
+ g->totalbytes -= (debt - g->GCdebt);
+ g->GCdebt = debt;
}
-static void freestack (lua_State *L, lua_State *L1) {
- luaM_freearray(L, L1->base_ci, L1->size_ci, CallInfo);
- luaM_freearray(L, L1->stack, L1->stacksize, TValue);
+CallInfo *luaE_extendCI (lua_State *L) {
+ CallInfo *ci = luaM_new(L, CallInfo);
+ lua_assert(L->ci->next == NULL);
+ L->ci->next = ci;
+ ci->previous = L->ci;
+ ci->next = NULL;
+ return ci;
+}
+
+
+void luaE_freeCI (lua_State *L) {
+ CallInfo *ci = L->ci;
+ CallInfo *next = ci->next;
+ ci->next = NULL;
+ while ((ci = next) != NULL) {
+ next = ci->next;
+ luaM_free(L, ci);
+ }
+}
+
+
+static void stack_init (lua_State *L1, lua_State *L) {
+ int i; CallInfo *ci;
+ /* initialize stack array */
+ L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, TValue);
+ L1->stacksize = BASIC_STACK_SIZE;
+ for (i = 0; i < BASIC_STACK_SIZE; i++)
+ setnilvalue(L1->stack + i); /* erase new stack */
+ L1->top = L1->stack;
+ L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK;
+ /* initialize first ci */
+ ci = &L1->base_ci;
+ ci->next = ci->previous = NULL;
+ ci->callstatus = 0;
+ ci->func = L1->top;
+ setnilvalue(L1->top++); /* 'function' entry for this 'ci' */
+ ci->top = L1->top + LUA_MINSTACK;
+ L1->ci = ci;
+}
+
+
+static void freestack (lua_State *L) {
+ if (L->stack == NULL)
+ return; /* stack not completely built yet */
+ L->ci = &L->base_ci; /* free the entire 'ci' list */
+ luaE_freeCI(L);
+ luaM_freearray(L, L->stack, L->stacksize); /* free stack array */
}
/*
-** open parts that may cause memory-allocation errors
+** Create registry table and its predefined values
+*/
+static void init_registry (lua_State *L, global_State *g) {
+ TValue mt;
+ /* create registry */
+ Table *registry = luaH_new(L);
+ sethvalue(L, &g->l_registry, registry);
+ luaH_resize(L, registry, LUA_RIDX_LAST, 0);
+ /* registry[LUA_RIDX_MAINTHREAD] = L */
+ setthvalue(L, &mt, L);
+ luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);
+ /* registry[LUA_RIDX_GLOBALS] = table of globals */
+ sethvalue(L, &mt, luaH_new(L));
+ luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);
+}
+
+
+/*
+** open parts of the state that may cause memory-allocation errors
*/
static void f_luaopen (lua_State *L, void *ud) {
global_State *g = G(L);
UNUSED(ud);
stack_init(L, L); /* init stack */
- sethvalue(L, gt(L), luaH_new(L, 0, 2)); /* table of globals */
- sethvalue(L, registry(L), luaH_new(L, 0, 2)); /* registry */
+ init_registry(L, g);
luaS_resize(L, MINSTRTABSIZE); /* initial size of string table */
luaT_init(L);
luaX_init(L);
- luaS_fix(luaS_newliteral(L, MEMERRMSG));
- g->GCthreshold = 4*g->totalbytes;
+ /* pre-create memory-error message */
+ g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
+ luaS_fix(g->memerrmsg); /* it should never be collected */
+ g->gcrunning = 1; /* allow gc */
}
+/*
+** preinitialize a state with consistent values without allocating
+** any memory (to avoid errors)
+*/
static void preinit_state (lua_State *L, global_State *g) {
G(L) = g;
L->stack = NULL;
+ L->ci = NULL;
L->stacksize = 0;
L->errorJmp = NULL;
+ L->nCcalls = 0;
L->hook = NULL;
L->hookmask = 0;
L->basehookcount = 0;
L->allowhook = 1;
resethookcount(L);
L->openupval = NULL;
- L->size_ci = 0;
- L->nCcalls = L->baseCcalls = 0;
- L->status = 0;
- L->base_ci = L->ci = NULL;
- L->savedpc = NULL;
+ L->nny = 1;
+ L->status = LUA_OK;
L->errfunc = 0;
- setnilvalue(gt(L));
}
static void close_state (lua_State *L) {
global_State *g = G(L);
luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_freeall(L); /* collect all objects */
- lua_assert(g->rootgc == obj2gco(L));
- lua_assert(g->strt.nuse == 0);
- luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size, TString *);
+ luaC_freeallobjects(L); /* collect all objects */
+ luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
luaZ_freebuffer(L, &g->buff);
- freestack(L, L);
- lua_assert(g->totalbytes == sizeof(LG));
- (*g->frealloc)(g->ud, fromstate(L), state_size(LG), 0);
+ freestack(L);
+ lua_assert(gettotalbytes(g) == sizeof(LG));
+ (*g->frealloc)(g->ud, fromstate(L), sizeof(LG), 0); /* free main block */
}
-lua_State *luaE_newthread (lua_State *L) {
- lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State)));
- luaC_link(L, obj2gco(L1), LUA_TTHREAD);
+LUA_API lua_State *lua_newthread (lua_State *L) {
+ lua_State *L1;
+ lua_lock(L);
+ luaC_checkGC(L);
+ L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;
+ setthvalue(L, L->top, L1);
+ api_incr_top(L);
preinit_state(L1, G(L));
- stack_init(L1, L); /* init stack */
- setobj2n(L, gt(L1), gt(L)); /* share table of globals */
L1->hookmask = L->hookmask;
L1->basehookcount = L->basehookcount;
L1->hook = L->hook;
resethookcount(L1);
- lua_assert(iswhite(obj2gco(L1)));
+ luai_userstatethread(L, L1);
+ stack_init(L1, L); /* init stack */
+ lua_unlock(L);
return L1;
}
void luaE_freethread (lua_State *L, lua_State *L1) {
+ LX *l = fromstate(L1);
luaF_close(L1, L1->stack); /* close all upvalues for this thread */
lua_assert(L1->openupval == NULL);
- luai_userstatefree(L1);
- freestack(L, L1);
- luaM_freemem(L, fromstate(L1), state_size(lua_State));
+ luai_userstatefree(L, L1);
+ freestack(L1);
+ luaM_free(L, l);
}
@@ -145,42 +229,43 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
int i;
lua_State *L;
global_State *g;
- void *l = (*f)(ud, NULL, 0, state_size(LG));
+ LG *l = cast(LG *, (*f)(ud, NULL, LUA_TTHREAD, sizeof(LG)));
if (l == NULL) return NULL;
- L = tostate(l);
- g = &((LG *)L)->g;
+ L = &l->l.l;
+ g = &l->g;
L->next = NULL;
L->tt = LUA_TTHREAD;
g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);
L->marked = luaC_white(g);
- set2bits(L->marked, FIXEDBIT, SFIXEDBIT);
+ g->gckind = KGC_NORMAL;
preinit_state(L, g);
g->frealloc = f;
g->ud = ud;
g->mainthread = L;
g->uvhead.u.l.prev = &g->uvhead;
g->uvhead.u.l.next = &g->uvhead;
- g->GCthreshold = 0; /* mark it as unfinished state */
+ g->gcrunning = 0; /* no GC while building state */
+ g->lastmajormem = 0;
g->strt.size = 0;
g->strt.nuse = 0;
g->strt.hash = NULL;
- setnilvalue(registry(L));
+ setnilvalue(&g->l_registry);
luaZ_initbuffer(L, &g->buff);
g->panic = NULL;
+ g->version = lua_version(NULL);
g->gcstate = GCSpause;
- g->rootgc = obj2gco(L);
- g->sweepstrgc = 0;
- g->sweepgc = &g->rootgc;
- g->gray = NULL;
- g->grayagain = NULL;
- g->weak = NULL;
- g->tmudata = NULL;
+ g->allgc = NULL;
+ g->finobj = NULL;
+ g->tobefnz = NULL;
+ g->gray = g->grayagain = NULL;
+ g->weak = g->ephemeron = g->allweak = NULL;
g->totalbytes = sizeof(LG);
+ g->GCdebt = 0;
g->gcpause = LUAI_GCPAUSE;
+ g->gcmajorinc = LUAI_GCMAJOR;
g->gcstepmul = LUAI_GCMUL;
- g->gcdept = 0;
- for (i=0; imt[i] = NULL;
- if (luaD_rawrunprotected(L, f_luaopen, NULL) != 0) {
+ for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
+ if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
/* memory allocation error: free partial state */
close_state(L);
L = NULL;
@@ -191,25 +276,11 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) {
}
-static void callallgcTM (lua_State *L, void *ud) {
- UNUSED(ud);
- luaC_callGCTM(L); /* call GC metamethods for all udata */
-}
-
-
LUA_API void lua_close (lua_State *L) {
L = G(L)->mainthread; /* only the main thread can be closed */
lua_lock(L);
- luaF_close(L, L->stack); /* close all upvalues for this thread */
- luaC_separateudata(L, 1); /* separate udata that have GC metamethods */
- L->errfunc = 0; /* no error function during GC metamethods */
- do { /* repeat until no more errors */
- L->ci = L->base_ci;
- L->base = L->top = L->ci->base;
- L->nCcalls = L->baseCcalls = 0;
- } while (luaD_rawrunprotected(L, callallgcTM, NULL) != 0);
- lua_assert(G(L)->tmudata == NULL);
luai_userstateclose(L);
close_state(L);
}
+
diff --git a/l2detect/lua/lstate.h b/l2detect/lua/lstate.h
index 3bc575b..4743d74 100644
--- a/l2detect/lua/lstate.h
+++ b/l2detect/lua/lstate.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstate.h,v 2.24.1.2 2008/01/03 15:20:39 roberto Exp $
+** $Id: lstate.h,v 2.74 2011/09/30 12:45:07 roberto Exp $
** Global State
** See Copyright Notice in lua.h
*/
@@ -14,26 +14,47 @@
#include "lzio.h"
+/*
+
+** Some notes about garbage-collected objects: All objects in Lua must
+** be kept somehow accessible until being freed.
+**
+** Lua keeps most objects linked in list g->allgc. The link uses field
+** 'next' of the CommonHeader.
+**
+** Strings are kept in several lists headed by the array g->strt.hash.
+**
+** Open upvalues are not subject to independent garbage collection. They
+** are collected together with their respective threads. Lua keeps a
+** double-linked list with all open upvalues (g->uvhead) so that it can
+** mark objects referred by them. (They are always gray, so they must
+** be remarked in the atomic step. Usually their contents would be marked
+** when traversing the respective threads, but the thread may already be
+** dead, while the upvalue is still accessible through closures.)
+**
+** Objects with finalizers are kept in the list g->finobj.
+**
+** The list g->tobefnz links all objects being finalized.
+
+*/
+
struct lua_longjmp; /* defined in ldo.c */
-/* table of globals */
-#define gt(L) (&L->l_gt)
-
-/* registry */
-#define registry(L) (&G(L)->l_registry)
-
/* extra stack space to handle TM calls and some other extras */
#define EXTRA_STACK 5
-#define BASIC_CI_SIZE 8
-
#define BASIC_STACK_SIZE (2*LUA_MINSTACK)
+/* kinds of Garbage Collection */
+#define KGC_NORMAL 0
+#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */
+#define KGC_GEN 2 /* generational collection */
+
typedef struct stringtable {
GCObject **hash;
@@ -43,54 +64,83 @@ typedef struct stringtable {
/*
-** informations about a call
+** information about a call
*/
typedef struct CallInfo {
- StkId base; /* base for this function */
StkId func; /* function index in the stack */
StkId top; /* top for this function */
- const Instruction *savedpc;
- int nresults; /* expected number of results from this function */
- int tailcalls; /* number of tail calls lost under this entry */
+ struct CallInfo *previous, *next; /* dynamic call link */
+ short nresults; /* expected number of results from this function */
+ lu_byte callstatus;
+ union {
+ struct { /* only for Lua functions */
+ StkId base; /* base for this function */
+ const Instruction *savedpc;
+ } l;
+ struct { /* only for C functions */
+ int ctx; /* context info. in case of yields */
+ lua_CFunction k; /* continuation in case of yields */
+ ptrdiff_t old_errfunc;
+ ptrdiff_t extra;
+ lu_byte old_allowhook;
+ lu_byte status;
+ } c;
+ } u;
} CallInfo;
+/*
+** Bits in CallInfo status
+*/
+#define CIST_LUA (1<<0) /* call is running a Lua function */
+#define CIST_HOOKED (1<<1) /* call is running a debug hook */
+#define CIST_REENTRY (1<<2) /* call is running on same invocation of
+ luaV_execute of previous call */
+#define CIST_YIELDED (1<<3) /* call reentered after suspension */
+#define CIST_YPCALL (1<<4) /* call is a yieldable protected call */
+#define CIST_STAT (1<<5) /* call has an error status (pcall) */
+#define CIST_TAIL (1<<6) /* call was tail called */
-#define curr_func(L) (clvalue(L->ci->func))
-#define ci_func(ci) (clvalue((ci)->func))
-#define f_isLua(ci) (!ci_func(ci)->c.isC)
-#define isLua(ci) (ttisfunction((ci)->func) && f_isLua(ci))
+
+#define isLua(ci) ((ci)->callstatus & CIST_LUA)
/*
** `global state', shared by all threads of this state
*/
typedef struct global_State {
- stringtable strt; /* hash table for strings */
lua_Alloc frealloc; /* function to reallocate memory */
void *ud; /* auxiliary data to `frealloc' */
+ lu_mem totalbytes; /* number of bytes currently allocated - GCdebt */
+ l_mem GCdebt; /* bytes allocated not yet compensated by the collector */
+ lu_mem lastmajormem; /* memory in use after last major collection */
+ stringtable strt; /* hash table for strings */
+ TValue l_registry;
lu_byte currentwhite;
lu_byte gcstate; /* state of garbage collector */
+ lu_byte gckind; /* kind of GC running */
+ lu_byte gcrunning; /* true if GC is running */
int sweepstrgc; /* position of sweep in `strt' */
- GCObject *rootgc; /* list of all collectable objects */
- GCObject **sweepgc; /* position of sweep in `rootgc' */
+ GCObject *allgc; /* list of all collectable objects */
+ GCObject *finobj; /* list of collectable objects with finalizers */
+ GCObject **sweepgc; /* current position of sweep */
GCObject *gray; /* list of gray objects */
GCObject *grayagain; /* list of objects to be traversed atomically */
- GCObject *weak; /* list of weak tables (to be cleared) */
- GCObject *tmudata; /* last element of list of userdata to be GC */
- Mbuffer buff; /* temporary buffer for string concatentation */
- lu_mem GCthreshold;
- lu_mem totalbytes; /* number of bytes currently allocated */
- lu_mem estimate; /* an estimate of number of bytes actually in use */
- lu_mem gcdept; /* how much GC is `behind schedule' */
+ GCObject *weak; /* list of tables with weak values */
+ GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
+ GCObject *allweak; /* list of all-weak tables */
+ GCObject *tobefnz; /* list of userdata to be GC */
+ UpVal uvhead; /* head of double-linked list of all open upvalues */
+ Mbuffer buff; /* temporary buffer for string concatenation */
int gcpause; /* size of pause between successive GCs */
+ int gcmajorinc; /* how much to wait for a major GC (only in gen. mode) */
int gcstepmul; /* GC `granularity' */
lua_CFunction panic; /* to be called in unprotected errors */
- TValue l_registry;
struct lua_State *mainthread;
- UpVal uvhead; /* head of double-linked list of all open upvalues */
- struct Table *mt[NUM_TAGS]; /* metatables for basic types */
+ const lua_Number *version; /* pointer to version number */
+ TString *memerrmsg; /* memory-error message */
TString *tmname[TM_N]; /* array with tag-method names */
+ struct Table *mt[LUA_NUMTAGS]; /* metatables for basic types */
} global_State;
@@ -101,29 +151,24 @@ struct lua_State {
CommonHeader;
lu_byte status;
StkId top; /* first free slot in the stack */
- StkId base; /* base of current function */
global_State *l_G;
CallInfo *ci; /* call info for current function */
- const Instruction *savedpc; /* `savedpc' of current function */
+ const Instruction *oldpc; /* last pc traced */
StkId stack_last; /* last free slot in the stack */
StkId stack; /* stack base */
- CallInfo *end_ci; /* points after end of ci array*/
- CallInfo *base_ci; /* array of CallInfo's */
int stacksize;
- int size_ci; /* size of array `base_ci' */
+ unsigned short nny; /* number of non-yieldable calls in stack */
unsigned short nCcalls; /* number of nested C calls */
- unsigned short baseCcalls; /* nested C calls when resuming coroutine */
lu_byte hookmask;
lu_byte allowhook;
int basehookcount;
int hookcount;
lua_Hook hook;
- TValue l_gt; /* table of globals */
- TValue env; /* temporary place for environments */
GCObject *openupval; /* list of open upvalues in this stack */
GCObject *gclist;
struct lua_longjmp *errorJmp; /* current error recover point */
ptrdiff_t errfunc; /* current error handling function (stack index) */
+ CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
};
@@ -134,7 +179,7 @@ struct lua_State {
** Union of all collectable objects
*/
union GCObject {
- GCheader gch;
+ GCheader gch; /* common header */
union TString ts;
union Udata u;
union Closure cl;
@@ -145,25 +190,31 @@ union GCObject {
};
+#define gch(o) (&(o)->gch)
+
/* macros to convert a GCObject into a specific value */
#define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
#define gco2ts(o) (&rawgco2ts(o)->tsv)
#define rawgco2u(o) check_exp((o)->gch.tt == LUA_TUSERDATA, &((o)->u))
#define gco2u(o) (&rawgco2u(o)->uv)
#define gco2cl(o) check_exp((o)->gch.tt == LUA_TFUNCTION, &((o)->cl))
-#define gco2h(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
+#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
-#define ngcotouv(o) \
- check_exp((o) == NULL || (o)->gch.tt == LUA_TUPVAL, &((o)->uv))
#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
/* macro to convert any Lua object into a GCObject */
#define obj2gco(v) (cast(GCObject *, (v)))
-LUAI_FUNC lua_State *luaE_newthread (lua_State *L);
+/* actual number of total bytes allocated */
+#define gettotalbytes(g) ((g)->totalbytes + (g)->GCdebt)
+
+LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt);
LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
+LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
+LUAI_FUNC void luaE_freeCI (lua_State *L);
+
#endif
diff --git a/l2detect/lua/lstring.c b/l2detect/lua/lstring.c
index db91d85..64eb859 100644
--- a/l2detect/lua/lstring.c
+++ b/l2detect/lua/lstring.c
@@ -1,12 +1,11 @@
/*
-** $Id: lstring.c,v 2.8.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lstring.c,v 2.19 2011/05/03 16:01:57 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
-
-//#include
#include "stdafx.h"
+//#include
#define lstring_c
#define LUA_CORE
@@ -21,54 +20,55 @@
void luaS_resize (lua_State *L, int newsize) {
- GCObject **newhash;
- stringtable *tb;
int i;
- if (G(L)->gcstate == GCSsweepstring)
- return; /* cannot resize during GC traverse */
- newhash = luaM_newvector(L, newsize, GCObject *);
- tb = &G(L)->strt;
- for (i=0; istrt;
+ /* cannot resize while GC is traversing strings */
+ luaC_runtilstate(L, ~bitmask(GCSsweepstring));
+ if (newsize > tb->size) {
+ luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
+ for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
+ }
/* rehash */
for (i=0; isize; i++) {
GCObject *p = tb->hash[i];
+ tb->hash[i] = NULL;
while (p) { /* for each node in the list */
- GCObject *next = p->gch.next; /* save next */
- unsigned int h = gco2ts(p)->hash;
- int h1 = lmod(h, newsize); /* new position */
- lua_assert(cast_int(h%newsize) == lmod(h, newsize));
- p->gch.next = newhash[h1]; /* chain it */
- newhash[h1] = p;
+ GCObject *next = gch(p)->next; /* save next */
+ unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */
+ gch(p)->next = tb->hash[h]; /* chain it */
+ tb->hash[h] = p;
+ resetoldbit(p); /* see MOVE OLD rule */
p = next;
}
}
- luaM_freearray(L, tb->hash, tb->size, TString *);
+ if (newsize < tb->size) {
+ /* shrinking slice must be empty */
+ lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
+ luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);
+ }
tb->size = newsize;
- tb->hash = newhash;
}
static TString *newlstr (lua_State *L, const char *str, size_t l,
unsigned int h) {
+ size_t totalsize; /* total size of TString object */
+ GCObject **list; /* (pointer to) list where it will be inserted */
TString *ts;
- stringtable *tb;
+ stringtable *tb = &G(L)->strt;
if (l+1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
luaM_toobig(L);
- ts = cast(TString *, luaM_malloc(L, (l+1)*sizeof(char)+sizeof(TString)));
+ if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
+ luaS_resize(L, tb->size*2); /* too crowded */
+ totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
+ list = &tb->hash[lmod(h, tb->size)];
+ ts = &luaC_newobj(L, LUA_TSTRING, totalsize, list, 0)->ts;
ts->tsv.len = l;
ts->tsv.hash = h;
- ts->tsv.marked = luaC_white(G(L));
- ts->tsv.tt = LUA_TSTRING;
ts->tsv.reserved = 0;
memcpy(ts+1, str, l*sizeof(char));
((char *)(ts+1))[l] = '\0'; /* ending 0 */
- tb = &G(L)->strt;
- h = lmod(h, tb->size);
- ts->tsv.next = tb->hash[h]; /* chain new entry */
- tb->hash[h] = obj2gco(ts);
tb->nuse++;
- if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
- luaS_resize(L, tb->size*2); /* too crowded */
return ts;
}
@@ -82,15 +82,22 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
h = h ^ ((h<<5)+(h>>2)+cast(unsigned char, str[l1-1]));
for (o = G(L)->strt.hash[lmod(h, G(L)->strt.size)];
o != NULL;
- o = o->gch.next) {
+ o = gch(o)->next) {
TString *ts = rawgco2ts(o);
- if (ts->tsv.len == l && (memcmp(str, getstr(ts), l) == 0)) {
- /* string may be dead */
- if (isdead(G(L), o)) changewhite(o);
+ if (h == ts->tsv.hash &&
+ ts->tsv.len == l &&
+ (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
+ if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */
+ changewhite(o); /* resurrect it */
return ts;
}
}
- return newlstr(L, str, l, h); /* not found */
+ return newlstr(L, str, l, h); /* not found; create a new string */
+}
+
+
+TString *luaS_new (lua_State *L, const char *str) {
+ return luaS_newlstr(L, str, strlen(str));
}
@@ -98,15 +105,10 @@ Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
if (s > MAX_SIZET - sizeof(Udata))
luaM_toobig(L);
- u = cast(Udata *, luaM_malloc(L, s + sizeof(Udata)));
- u->uv.marked = luaC_white(G(L)); /* is not finalized */
- u->uv.tt = LUA_TUSERDATA;
+ u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;
u->uv.len = s;
u->uv.metatable = NULL;
u->uv.env = e;
- /* chain it on udata list (after main thread) */
- u->uv.next = G(L)->mainthread->next;
- G(L)->mainthread->next = obj2gco(u);
return u;
}
diff --git a/l2detect/lua/lstring.h b/l2detect/lua/lstring.h
index 73a2ff8..d708a1b 100644
--- a/l2detect/lua/lstring.h
+++ b/l2detect/lua/lstring.h
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.h,v 1.43.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lstring.h,v 1.46 2010/04/05 16:26:37 roberto Exp $
** String table (keep all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -7,7 +7,6 @@
#ifndef lstring_h
#define lstring_h
-
#include "lgc.h"
#include "lobject.h"
#include "lstate.h"
@@ -17,15 +16,22 @@
#define sizeudata(u) (sizeof(union Udata)+(u)->len)
-#define luaS_new(L, s) (luaS_newlstr(L, s, strlen(s)))
#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
(sizeof(s)/sizeof(char))-1))
#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
+
+/*
+** as all string are internalized, string equality becomes
+** pointer equality
+*/
+#define eqstr(a,b) ((a) == (b))
+
LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
+LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
#endif
diff --git a/l2detect/lua/lstrlib.c b/l2detect/lua/lstrlib.c
index 51eeb9b..23eada8 100644
--- a/l2detect/lua/lstrlib.c
+++ b/l2detect/lua/lstrlib.c
@@ -1,16 +1,15 @@
/*
-** $Id: lstrlib.c,v 1.132.1.4 2008/07/11 17:27:21 roberto Exp $
+** $Id: lstrlib.c,v 1.173 2011/11/30 18:24:56 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
-
+#include "stdafx.h"
//#include
//#include
//#include
//#include
//#include
-#include "stdafx.h"
#define lstrlib_c
#define LUA_LIB
@@ -21,6 +20,15 @@
#include "lualib.h"
+/*
+** maximum number of captures that a pattern can do during
+** pattern-matching. This limit is arbitrary.
+*/
+#if !defined(LUA_MAXCAPTURES)
+#define LUA_MAXCAPTURES 32
+#endif
+
+
/* macro to `unsign' a character */
#define uchar(c) ((unsigned char)(c))
@@ -29,39 +37,41 @@
static int str_len (lua_State *L) {
size_t l;
luaL_checklstring(L, 1, &l);
- lua_pushinteger(L, l);
+ lua_pushinteger(L, (lua_Integer)l);
return 1;
}
-static ptrdiff_t posrelat (ptrdiff_t pos, size_t len) {
- /* relative string position: negative means back from end */
- if (pos < 0) pos += (ptrdiff_t)len + 1;
- return (pos >= 0) ? pos : 0;
+/* translate a relative string position: negative means back from end */
+static size_t posrelat (ptrdiff_t pos, size_t len) {
+ if (pos >= 0) return (size_t)pos;
+ else if (0u - (size_t)pos > len) return 0;
+ else return len - ((size_t)-pos) + 1;
}
static int str_sub (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
- ptrdiff_t start = posrelat(luaL_checkinteger(L, 2), l);
- ptrdiff_t end = posrelat(luaL_optinteger(L, 3, -1), l);
+ size_t start = posrelat(luaL_checkinteger(L, 2), l);
+ size_t end = posrelat(luaL_optinteger(L, 3, -1), l);
if (start < 1) start = 1;
- if (end > (ptrdiff_t)l) end = (ptrdiff_t)l;
+ if (end > l) end = l;
if (start <= end)
- lua_pushlstring(L, s+start-1, end-start+1);
+ lua_pushlstring(L, s + start - 1, end - start + 1);
else lua_pushliteral(L, "");
return 1;
}
static int str_reverse (lua_State *L) {
- size_t l;
+ size_t l, i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
- while (l--) luaL_addchar(&b, s[l]);
- luaL_pushresult(&b);
+ char *p = luaL_buffinitsize(L, &b, l);
+ for (i = 0; i < l; i++)
+ p[i] = s[l - i - 1];
+ luaL_pushresultsize(&b, l);
return 1;
}
@@ -71,10 +81,10 @@ static int str_lower (lua_State *L) {
size_t i;
luaL_Buffer b;
const char *s = luaL_checklstring(L, 1, &l);
- luaL_buffinit(L, &b);
+ char *p = luaL_buffinitsize(L, &b, l);
for (i=0; i> 1)
+
static int str_rep (lua_State *L) {
- size_t l;
- luaL_Buffer b;
+ size_t l, lsep;
const char *s = luaL_checklstring(L, 1, &l);
int n = luaL_checkint(L, 2);
- luaL_buffinit(L, &b);
- while (n-- > 0)
- luaL_addlstring(&b, s, l);
- luaL_pushresult(&b);
+ const char *sep = luaL_optlstring(L, 3, "", &lsep);
+ if (n <= 0) lua_pushliteral(L, "");
+ else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */
+ return luaL_error(L, "resulting string too large");
+ else {
+ size_t totallen = n * l + (n - 1) * lsep;
+ luaL_Buffer b;
+ char *p = luaL_buffinitsize(L, &b, totallen);
+ while (n-- > 1) { /* first n-1 copies (followed by separator) */
+ memcpy(p, s, l * sizeof(char)); p += l;
+ memcpy(p, sep, lsep * sizeof(char)); p += lsep;
+ }
+ memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */
+ luaL_pushresultsize(&b, totallen);
+ }
return 1;
}
@@ -107,15 +131,15 @@ static int str_rep (lua_State *L) {
static int str_byte (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
- ptrdiff_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
- ptrdiff_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
+ size_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
+ size_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
int n, i;
- if (posi <= 0) posi = 1;
- if ((size_t)pose > l) pose = l;
+ if (posi < 1) posi = 1;
+ if (pose > l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* overflow? */
- luaL_error(L, "string slice too long");
+ if (posi + n <= pose) /* (size_t -> int) overflow? */
+ return luaL_error(L, "string slice too long");
luaL_checkstack(L, n, "string slice too long");
for (i=0; i= ms->level || ms->capture[l].len == CAP_UNFINISHED)
- return luaL_error(ms->L, "invalid capture index");
+ return luaL_error(ms->L, "invalid capture index %%%d", l + 1);
return l;
}
@@ -203,16 +228,16 @@ static int capture_to_close (MatchState *ms) {
static const char *classend (MatchState *ms, const char *p) {
switch (*p++) {
case L_ESC: {
- if (*p == '\0')
+ if (p == ms->p_end)
luaL_error(ms->L, "malformed pattern (ends with " LUA_QL("%%") ")");
return p+1;
}
case '[': {
if (*p == '^') p++;
do { /* look for a `]' */
- if (*p == '\0')
+ if (p == ms->p_end)
luaL_error(ms->L, "malformed pattern (missing " LUA_QL("]") ")");
- if (*(p++) == L_ESC && *p != '\0')
+ if (*(p++) == L_ESC && p < ms->p_end)
p++; /* skip escapes (e.g. `%]') */
} while (*p != ']');
return p+1;
@@ -230,13 +255,14 @@ static int match_class (int c, int cl) {
case 'a' : res = isalpha(c); break;
case 'c' : res = iscntrl(c); break;
case 'd' : res = isdigit(c); break;
+ case 'g' : res = isgraph(c); break;
case 'l' : res = islower(c); break;
case 'p' : res = ispunct(c); break;
case 's' : res = isspace(c); break;
case 'u' : res = isupper(c); break;
case 'w' : res = isalnum(c); break;
case 'x' : res = isxdigit(c); break;
- case 'z' : res = (c == 0); break;
+ case 'z' : res = (c == 0); break; /* deprecated option */
default: return (cl == c);
}
return (islower(cl) ? res : !res);
@@ -281,8 +307,9 @@ static const char *match (MatchState *ms, const char *s, const char *p);
static const char *matchbalance (MatchState *ms, const char *s,
const char *p) {
- if (*p == 0 || *(p+1) == 0)
- luaL_error(ms->L, "unbalanced pattern");
+ if (p >= ms->p_end - 1)
+ luaL_error(ms->L, "malformed pattern "
+ "(missing arguments to " LUA_QL("%%b") ")");
if (*s != *p) return NULL;
else {
int b = *p;
@@ -365,6 +392,8 @@ static const char *match_capture (MatchState *ms, const char *s, int l) {
static const char *match (MatchState *ms, const char *s, const char *p) {
init: /* using goto's to optimize tail recursion */
+ if (p == ms->p_end) /* end of pattern? */
+ return s; /* match succeeded */
switch (*p) {
case '(': { /* start capture */
if (*(p+1) == ')') /* position capture? */
@@ -375,7 +404,12 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
case ')': { /* end capture */
return end_capture(ms, s, p+1);
}
- case L_ESC: {
+ case '$': {
+ if ((p+1) == ms->p_end) /* is the `$' the last char in pattern? */
+ return (s == ms->src_end) ? s : NULL; /* check end of string */
+ else goto dflt;
+ }
+ case L_ESC: { /* escaped sequences not in the format class[*+?-]? */
switch (*(p+1)) {
case 'b': { /* balanced string? */
s = matchbalance(ms, s, p+2);
@@ -394,27 +428,19 @@ static const char *match (MatchState *ms, const char *s, const char *p) {
!matchbracketclass(uchar(*s), p, ep-1)) return NULL;
p=ep; goto init; /* else return match(ms, s, ep); */
}
- default: {
- if (isdigit(uchar(*(p+1)))) { /* capture results (%0-%9)? */
- s = match_capture(ms, s, uchar(*(p+1)));
- if (s == NULL) return NULL;
- p+=2; goto init; /* else return match(ms, s, p+2) */
- }
- goto dflt; /* case default */
+ case '0': case '1': case '2': case '3':
+ case '4': case '5': case '6': case '7':
+ case '8': case '9': { /* capture results (%0-%9)? */
+ s = match_capture(ms, s, uchar(*(p+1)));
+ if (s == NULL) return NULL;
+ p+=2; goto init; /* else return match(ms, s, p+2) */
}
+ default: goto dflt;
}
}
- case '\0': { /* end of pattern */
- return s; /* match succeeded */
- }
- case '$': {
- if (*(p+1) == '\0') /* is the `$' the last char in pattern? */
- return (s == ms->src_end) ? s : NULL; /* check end of string */
- else goto dflt;
- }
- default: dflt: { /* it is a pattern item */
+ default: dflt: { /* pattern class plus optional suffix */
const char *ep = classend(ms, p); /* points to what is next */
- int m = ssrc_end && singlematch(uchar(*s), p, ep);
+ int m = s < ms->src_end && singlematch(uchar(*s), p, ep);
switch (*ep) {
case '?': { /* optional */
const char *res;
@@ -493,37 +519,56 @@ static int push_captures (MatchState *ms, const char *s, const char *e) {
}
+/* check whether pattern has no special characters */
+static int nospecials (const char *p, size_t l) {
+ size_t upto = 0;
+ do {
+ if (strpbrk(p + upto, SPECIALS))
+ return 0; /* pattern has a special character */
+ upto += strlen(p + upto) + 1; /* may have more after \0 */
+ } while (upto <= l);
+ return 1; /* no special chars found */
+}
+
+
static int str_find_aux (lua_State *L, int find) {
- size_t l1, l2;
- const char *s = luaL_checklstring(L, 1, &l1);
- const char *p = luaL_checklstring(L, 2, &l2);
- ptrdiff_t init = posrelat(luaL_optinteger(L, 3, 1), l1) - 1;
- if (init < 0) init = 0;
- else if ((size_t)(init) > l1) init = (ptrdiff_t)l1;
- if (find && (lua_toboolean(L, 4) || /* explicit request? */
- strpbrk(p, SPECIALS) == NULL)) { /* or no special characters? */
+ size_t ls, lp;
+ const char *s = luaL_checklstring(L, 1, &ls);
+ const char *p = luaL_checklstring(L, 2, &lp);
+ size_t init = posrelat(luaL_optinteger(L, 3, 1), ls);
+ if (init < 1) init = 1;
+ else if (init > ls + 1) { /* start after string's end? */
+ lua_pushnil(L); /* cannot find anything */
+ return 1;
+ }
+ /* explicit request or no special characters? */
+ if (find && (lua_toboolean(L, 4) || nospecials(p, lp))) {
/* do a plain search */
- const char *s2 = lmemfind(s+init, l1-init, p, l2);
+ const char *s2 = lmemfind(s + init - 1, ls - init + 1, p, lp);
if (s2) {
- lua_pushinteger(L, s2-s+1);
- lua_pushinteger(L, s2-s+l2);
+ lua_pushinteger(L, s2 - s + 1);
+ lua_pushinteger(L, s2 - s + lp);
return 2;
}
}
else {
MatchState ms;
- int anchor = (*p == '^') ? (p++, 1) : 0;
- const char *s1=s+init;
+ const char *s1 = s + init - 1;
+ int anchor = (*p == '^');
+ if (anchor) {
+ p++; lp--; /* skip anchor character */
+ }
ms.L = L;
ms.src_init = s;
- ms.src_end = s+l1;
+ ms.src_end = s + ls;
+ ms.p_end = p + lp;
do {
const char *res;
ms.level = 0;
if ((res=match(&ms, s1, p)) != NULL) {
if (find) {
- lua_pushinteger(L, s1-s+1); /* start */
- lua_pushinteger(L, res-s); /* end */
+ lua_pushinteger(L, s1 - s + 1); /* start */
+ lua_pushinteger(L, res - s); /* end */
return push_captures(&ms, NULL, 0) + 2;
}
else
@@ -548,13 +593,14 @@ static int str_match (lua_State *L) {
static int gmatch_aux (lua_State *L) {
MatchState ms;
- size_t ls;
+ size_t ls, lp;
const char *s = lua_tolstring(L, lua_upvalueindex(1), &ls);
- const char *p = lua_tostring(L, lua_upvalueindex(2));
+ const char *p = lua_tolstring(L, lua_upvalueindex(2), &lp);
const char *src;
ms.L = L;
ms.src_init = s;
ms.src_end = s+ls;
+ ms.p_end = p + lp;
for (src = s + (size_t)lua_tointeger(L, lua_upvalueindex(3));
src <= ms.src_end;
src++) {
@@ -582,12 +628,6 @@ static int gmatch (lua_State *L) {
}
-static int gfind_nodef (lua_State *L) {
- return luaL_error(L, LUA_QL("string.gfind") " was renamed to "
- LUA_QL("string.gmatch"));
-}
-
-
static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
const char *e) {
size_t l, i;
@@ -597,8 +637,12 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
luaL_addchar(b, news[i]);
else {
i++; /* skip ESC */
- if (!isdigit(uchar(news[i])))
+ if (!isdigit(uchar(news[i]))) {
+ if (news[i] != L_ESC)
+ luaL_error(ms->L, "invalid use of " LUA_QL("%c")
+ " in replacement string", L_ESC);
luaL_addchar(b, news[i]);
+ }
else if (news[i] == '0')
luaL_addlstring(b, s, e - s);
else {
@@ -611,14 +655,9 @@ static void add_s (MatchState *ms, luaL_Buffer *b, const char *s,
static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
- const char *e) {
+ const char *e, int tr) {
lua_State *L = ms->L;
- switch (lua_type(L, 3)) {
- case LUA_TNUMBER:
- case LUA_TSTRING: {
- add_s(ms, b, s, e);
- return;
- }
+ switch (tr) {
case LUA_TFUNCTION: {
int n;
lua_pushvalue(L, 3);
@@ -631,41 +670,49 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s,
lua_gettable(L, 3);
break;
}
+ default: { /* LUA_TNUMBER or LUA_TSTRING */
+ add_s(ms, b, s, e);
+ return;
+ }
}
if (!lua_toboolean(L, -1)) { /* nil or false? */
lua_pop(L, 1);
lua_pushlstring(L, s, e - s); /* keep original text */
}
else if (!lua_isstring(L, -1))
- luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
+ luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1));
luaL_addvalue(b); /* add result to accumulator */
}
static int str_gsub (lua_State *L) {
- size_t srcl;
+ size_t srcl, lp;
const char *src = luaL_checklstring(L, 1, &srcl);
- const char *p = luaL_checkstring(L, 2);
- int tr = lua_type(L, 3);
- int max_s = luaL_optint(L, 4, srcl+1);
- int anchor = (*p == '^') ? (p++, 1) : 0;
- int n = 0;
+ const char *p = luaL_checklstring(L, 2, &lp);
+ int tr = lua_type(L, 3);
+ size_t max_s = luaL_optinteger(L, 4, srcl+1);
+ int anchor = (*p == '^');
+ size_t n = 0;
MatchState ms;
luaL_Buffer b;
luaL_argcheck(L, tr == LUA_TNUMBER || tr == LUA_TSTRING ||
tr == LUA_TFUNCTION || tr == LUA_TTABLE, 3,
"string/function/table expected");
luaL_buffinit(L, &b);
+ if (anchor) {
+ p++; lp--; /* skip anchor character */
+ }
ms.L = L;
ms.src_init = src;
ms.src_end = src+srcl;
+ ms.p_end = p + lp;
while (n < max_s) {
const char *e;
ms.level = 0;
e = match(&ms, src, p);
if (e) {
n++;
- add_value(&ms, &b, src, e);
+ add_value(&ms, &b, src, e, tr);
}
if (e && e>src) /* non empty match? */
src = e; /* skip it */
@@ -683,6 +730,49 @@ static int str_gsub (lua_State *L) {
/* }====================================================== */
+
+/*
+** {======================================================
+** STRING FORMAT
+** =======================================================
+*/
+
+/*
+** LUA_INTFRMLEN is the length modifier for integer conversions in
+** 'string.format'; LUA_INTFRM_T is the integer type corresponding to
+** the previous length
+*/
+#if !defined(LUA_INTFRMLEN) /* { */
+#if defined(LUA_USE_LONGLONG)
+
+#define LUA_INTFRMLEN "ll"
+#define LUA_INTFRM_T long long
+
+#else
+
+#define LUA_INTFRMLEN "l"
+#define LUA_INTFRM_T long
+
+#endif
+#endif /* } */
+
+#define MAX_UINTFRM ((lua_Number)(~(unsigned LUA_INTFRM_T)0))
+#define MAX_INTFRM ((lua_Number)((~(unsigned LUA_INTFRM_T)0)/2))
+#define MIN_INTFRM (-(lua_Number)((~(unsigned LUA_INTFRM_T)0)/2) - 1)
+
+/*
+** LUA_FLTFRMLEN is the length modifier for float conversions in
+** 'string.format'; LUA_FLTFRM_T is the float type corresponding to
+** the previous length
+*/
+#if !defined(LUA_FLTFRMLEN)
+
+#define LUA_FLTFRMLEN ""
+#define LUA_FLTFRM_T double
+
+#endif
+
+
/* maximum size of each formatted item (> len(format('%99.99f', -1e308))) */
#define MAX_ITEM 512
/* valid flags in a format specification */
@@ -699,25 +789,20 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
const char *s = luaL_checklstring(L, arg, &l);
luaL_addchar(b, '"');
while (l--) {
- switch (*s) {
- case '"': case '\\': case '\n': {
- luaL_addchar(b, '\\');
- luaL_addchar(b, *s);
- break;
- }
- case '\r': {
- luaL_addlstring(b, "\\r", 2);
- break;
- }
- case '\0': {
- luaL_addlstring(b, "\\000", 4);
- break;
- }
- default: {
- luaL_addchar(b, *s);
- break;
- }
+ if (*s == '"' || *s == '\\' || *s == '\n') {
+ luaL_addchar(b, '\\');
+ luaL_addchar(b, *s);
}
+ else if (*s == '\0' || iscntrl(uchar(*s))) {
+ char buff[10];
+ if (!isdigit(uchar(*(s+1))))
+ sprintf(buff, "\\%d", (int)uchar(*s));
+ else
+ sprintf(buff, "\\%03d", (int)uchar(*s));
+ luaL_addstring(b, buff);
+ }
+ else
+ luaL_addchar(b, *s);
s++;
}
luaL_addchar(b, '"');
@@ -726,7 +811,7 @@ static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
const char *p = strfrmt;
while (*p != '\0' && strchr(FLAGS, *p) != NULL) p++; /* skip flags */
- if ((size_t)(p - strfrmt) >= sizeof(FLAGS))
+ if ((size_t)(p - strfrmt) >= sizeof(FLAGS)/sizeof(char))
luaL_error(L, "invalid format (repeated flags)");
if (isdigit(uchar(*p))) p++; /* skip width */
if (isdigit(uchar(*p))) p++; /* (2 digits at most) */
@@ -738,23 +823,28 @@ static const char *scanformat (lua_State *L, const char *strfrmt, char *form) {
if (isdigit(uchar(*p)))
luaL_error(L, "invalid format (width or precision too long)");
*(form++) = '%';
- strncpy(form, strfrmt, p - strfrmt + 1);
+ memcpy(form, strfrmt, (p - strfrmt + 1) * sizeof(char));
form += p - strfrmt + 1;
*form = '\0';
return p;
}
-static void addintlen (char *form) {
+/*
+** add length modifier into formats
+*/
+static void addlenmod (char *form, const char *lenmod) {
size_t l = strlen(form);
+ size_t lm = strlen(lenmod);
char spec = form[l - 1];
- strcpy(form + l - 1, LUA_INTFRMLEN);
- form[l + sizeof(LUA_INTFRMLEN) - 2] = spec;
- form[l + sizeof(LUA_INTFRMLEN) - 1] = '\0';
+ strcpy(form + l - 1, lenmod);
+ form[l + lm - 1] = spec;
+ form[l + lm] = '\0';
}
static int str_format (lua_State *L) {
+ int top = lua_gettop(L);
int arg = 1;
size_t sfl;
const char *strfrmt = luaL_checklstring(L, arg, &sfl);
@@ -768,45 +858,57 @@ static int str_format (lua_State *L) {
luaL_addchar(&b, *strfrmt++); /* %% */
else { /* format item */
char form[MAX_FORMAT]; /* to store the format (`%...') */
- char buff[MAX_ITEM]; /* to store the formatted item */
- arg++;
+ char *buff = luaL_prepbuffsize(&b, MAX_ITEM); /* to put formatted item */
+ int nb = 0; /* number of bytes in added item */
+ if (++arg > top)
+ luaL_argerror(L, arg, "no value");
strfrmt = scanformat(L, strfrmt, form);
switch (*strfrmt++) {
case 'c': {
- sprintf(buff, form, (int)luaL_checknumber(L, arg));
+ nb = sprintf(buff, form, luaL_checkint(L, arg));
break;
}
case 'd': case 'i': {
- addintlen(form);
- sprintf(buff, form, (LUA_INTFRM_T)luaL_checknumber(L, arg));
+ lua_Number n = luaL_checknumber(L, arg);
+ luaL_argcheck(L, (MIN_INTFRM - 1) < n && n < (MAX_INTFRM + 1), arg,
+ "not a number in proper range");
+ addlenmod(form, LUA_INTFRMLEN);
+ nb = sprintf(buff, form, (LUA_INTFRM_T)n);
break;
}
case 'o': case 'u': case 'x': case 'X': {
- addintlen(form);
- sprintf(buff, form, (unsigned LUA_INTFRM_T)luaL_checknumber(L, arg));
+ lua_Number n = luaL_checknumber(L, arg);
+ luaL_argcheck(L, 0 <= n && n < (MAX_UINTFRM + 1), arg,
+ "not a non-negative number in proper range");
+ addlenmod(form, LUA_INTFRMLEN);
+ nb = sprintf(buff, form, (unsigned LUA_INTFRM_T)n);
break;
}
case 'e': case 'E': case 'f':
+#if defined(LUA_USE_AFORMAT)
+ case 'a': case 'A':
+#endif
case 'g': case 'G': {
- sprintf(buff, form, (double)luaL_checknumber(L, arg));
+ addlenmod(form, LUA_FLTFRMLEN);
+ nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
break;
}
case 'q': {
addquoted(L, &b, arg);
- continue; /* skip the 'addsize' at the end */
+ break;
}
case 's': {
size_t l;
- const char *s = luaL_checklstring(L, arg, &l);
+ const char *s = luaL_tolstring(L, arg, &l);
if (!strchr(form, '.') && l >= 100) {
/* no precision and string is too long to be formatted;
keep original string */
- lua_pushvalue(L, arg);
luaL_addvalue(&b);
- continue; /* skip the `addsize' at the end */
+ break;
}
else {
- sprintf(buff, form, s);
+ nb = sprintf(buff, form, s);
+ lua_pop(L, 1); /* remove result from 'luaL_tolstring' */
break;
}
}
@@ -815,13 +917,15 @@ static int str_format (lua_State *L) {
LUA_QL("format"), *(strfrmt - 1));
}
}
- luaL_addlstring(&b, buff, strlen(buff));
+ luaL_addsize(&b, nb);
}
}
luaL_pushresult(&b);
return 1;
}
+/* }====================================================== */
+
static const luaL_Reg strlib[] = {
{"byte", str_byte},
@@ -829,7 +933,6 @@ static const luaL_Reg strlib[] = {
{"dump", str_dump},
{"find", str_find},
{"format", str_format},
- {"gfind", gfind_nodef},
{"gmatch", gmatch},
{"gsub", str_gsub},
{"len", str_len},
@@ -844,13 +947,13 @@ static const luaL_Reg strlib[] = {
static void createmetatable (lua_State *L) {
- lua_createtable(L, 0, 1); /* create metatable for strings */
+ lua_createtable(L, 0, 1); /* table to be metatable for strings */
lua_pushliteral(L, ""); /* dummy string */
- lua_pushvalue(L, -2);
- lua_setmetatable(L, -2); /* set string metatable */
+ lua_pushvalue(L, -2); /* copy table */
+ lua_setmetatable(L, -2); /* set table as metatable for strings */
lua_pop(L, 1); /* pop dummy string */
- lua_pushvalue(L, -2); /* string library... */
- lua_setfield(L, -2, "__index"); /* ...is the __index metamethod */
+ lua_pushvalue(L, -2); /* get string library */
+ lua_setfield(L, -2, "__index"); /* metatable.__index = string */
lua_pop(L, 1); /* pop metatable */
}
@@ -858,12 +961,8 @@ static void createmetatable (lua_State *L) {
/*
** Open string library
*/
-LUALIB_API int luaopen_string (lua_State *L) {
- luaL_register(L, LUA_STRLIBNAME, strlib);
-#if defined(LUA_COMPAT_GFIND)
- lua_getfield(L, -1, "gmatch");
- lua_setfield(L, -2, "gfind");
-#endif
+LUAMOD_API int luaopen_string (lua_State *L) {
+ luaL_newlib(L, strlib);
createmetatable(L);
return 1;
}
diff --git a/l2detect/lua/ltable.c b/l2detect/lua/ltable.c
index c8c4900..dadecab 100644
--- a/l2detect/lua/ltable.c
+++ b/l2detect/lua/ltable.c
@@ -1,9 +1,9 @@
/*
-** $Id: ltable.c,v 2.32.1.2 2007/12/28 15:32:23 roberto Exp $
+** $Id: ltable.c,v 2.67 2011/11/30 12:41:45 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
-
+#include "stdafx.h"
/*
** Implementation of tables (aka arrays, objects, or hash tables).
@@ -18,9 +18,7 @@
** Hence even when the load factor reaches 100%, performance remains good.
*/
-//#include
//#include
-#include "stdafx.h"
#define ltable_c
#define LUA_CORE
@@ -33,14 +31,16 @@
#include "lmem.h"
#include "lobject.h"
#include "lstate.h"
+#include "lstring.h"
#include "ltable.h"
+#include "lvm.h"
/*
** max size of array part is 2^MAXBITS
*/
-#if LUAI_BITSINT > 26
-#define MAXBITS 26
+#if LUAI_BITSINT >= 32
+#define MAXBITS 30
#else
#define MAXBITS (LUAI_BITSINT-2)
#endif
@@ -49,7 +49,7 @@
#define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t))))
-
+
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
@@ -64,18 +64,13 @@
#define hashpointer(t,p) hashmod(t, IntPoint(p))
-/*
-** number of ints inside a lua_Number
-*/
-#define numints cast_int(sizeof(lua_Number)/sizeof(int))
-
-
-
#define dummynode (&dummynode_)
+#define isdummy(n) ((n) == dummynode)
+
static const Node dummynode_ = {
- {{NULL}, LUA_TNIL}, /* value */
- {{{NULL}, LUA_TNIL, NULL}} /* key */
+ {NILCONSTANT}, /* value */
+ {{NILCONSTANT, NULL}} /* key */
};
@@ -83,13 +78,14 @@ static const Node dummynode_ = {
** hash for lua_Numbers
*/
static Node *hashnum (const Table *t, lua_Number n) {
- unsigned int a[numints];
int i;
- if (luai_numeq(n, 0)) /* avoid problems with -0 */
- return gnode(t, 0);
- memcpy(a, &n, sizeof(a));
- for (i = 1; i < numints; i++) a[0] += a[i];
- return hashmod(t, a[0]);
+ luai_hashnum(i, n);
+ if (i < 0) {
+ if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */
+ i = 0; /* handle INT_MIN */
+ i = -i; /* must be a positive value */
+ }
+ return hashmod(t, i);
}
@@ -108,6 +104,8 @@ static Node *mainposition (const Table *t, const TValue *key) {
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
return hashpointer(t, pvalue(key));
+ case LUA_TLCF:
+ return hashpointer(t, fvalue(key));
default:
return hashpointer(t, gcvalue(key));
}
@@ -133,7 +131,7 @@ static int arrayindex (const TValue *key) {
/*
** returns the index of a `key' for table traversals. First goes all
** elements in the array part, then elements in the hash part. The
-** beginning of a traversal is signalled by -1.
+** beginning of a traversal is signaled by -1.
*/
static int findindex (lua_State *L, Table *t, StkId key) {
int i;
@@ -143,19 +141,19 @@ static int findindex (lua_State *L, Table *t, StkId key) {
return i-1; /* yes; that's the index (corrected to C) */
else {
Node *n = mainposition(t, key);
- do { /* check whether `key' is somewhere in the chain */
+ for (;;) { /* check whether `key' is somewhere in the chain */
/* key may be dead already, but it is ok to use it in `next' */
- if (luaO_rawequalObj(key2tval(n), key) ||
- (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
- gcvalue(gkey(n)) == gcvalue(key))) {
+ if (luaV_rawequalobj(gkey(n), key) ||
+ (ttisdeadkey(gkey(n)) && iscollectable(key) &&
+ deadvalue(gkey(n)) == gcvalue(key))) {
i = cast_int(n - gnode(t, 0)); /* key index in hash table */
/* hash elements are numbered after array ones */
return i + t->sizearray;
}
else n = gnext(n);
- } while (n);
- luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
- return 0; /* to avoid warnings */
+ if (n == NULL)
+ luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
+ }
}
}
@@ -171,7 +169,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
}
for (i -= t->sizearray; i < sizenode(t); i++) { /* then hash part */
if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
- setobj2s(L, key, key2tval(gnode(t, i)));
+ setobj2s(L, key, gkey(gnode(t, i)));
setobj2s(L, key+1, gval(gnode(t, i)));
return 1;
}
@@ -212,7 +210,7 @@ static int computesizes (int nums[], int *narray) {
static int countint (const TValue *key, int *nums) {
int k = arrayindex(key);
if (0 < k && k <= MAXASIZE) { /* is `key' an appropriate array index? */
- nums[ceillog2(k)]++; /* count as such */
+ nums[luaO_ceillog2(k)]++; /* count as such */
return 1;
}
else
@@ -252,7 +250,7 @@ static int numusehash (const Table *t, int *nums, int *pnasize) {
while (i--) {
Node *n = &t->node[i];
if (!ttisnil(gval(n))) {
- ause += countint(key2tval(n), nums);
+ ause += countint(gkey(n), nums);
totaluse++;
}
}
@@ -278,7 +276,7 @@ static void setnodevector (lua_State *L, Table *t, int size) {
}
else {
int i;
- lsize = ceillog2(size);
+ lsize = luaO_ceillog2(size);
if (lsize > MAXBITS)
luaG_runerror(L, "table overflow");
size = twoto(lsize);
@@ -295,7 +293,7 @@ static void setnodevector (lua_State *L, Table *t, int size) {
}
-static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
+void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize) {
int i;
int oldasize = t->sizearray;
int oldhsize = t->lsizenode;
@@ -303,13 +301,13 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
if (nasize > oldasize) /* array part must grow? */
setarrayvector(L, t, nasize);
/* create new hash part with appropriate size */
- setnodevector(L, t, nhsize);
+ setnodevector(L, t, nhsize);
if (nasize < oldasize) { /* array part must shrink? */
t->sizearray = nasize;
/* re-insert elements from vanishing slice */
for (i=nasize; iarray[i]))
- setobjt2t(L, luaH_setnum(L, t, i+1), &t->array[i]);
+ luaH_setint(L, t, i + 1, &t->array[i]);
}
/* shrink array */
luaM_reallocvector(L, t->array, oldasize, nasize, TValue);
@@ -317,23 +315,26 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) {
/* re-insert elements from hash part */
for (i = twoto(oldhsize) - 1; i >= 0; i--) {
Node *old = nold+i;
- if (!ttisnil(gval(old)))
- setobjt2t(L, luaH_set(L, t, key2tval(old)), gval(old));
+ if (!ttisnil(gval(old))) {
+ /* doesn't need barrier/invalidate cache, as entry was
+ already present in the table */
+ setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old));
+ }
}
- if (nold != dummynode)
- luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */
+ if (!isdummy(nold))
+ luaM_freearray(L, nold, cast(size_t, twoto(oldhsize))); /* free old array */
}
void luaH_resizearray (lua_State *L, Table *t, int nasize) {
- int nsize = (t->node == dummynode) ? 0 : sizenode(t);
- resize(L, t, nasize, nsize);
+ int nsize = isdummy(t->node) ? 0 : sizenode(t);
+ luaH_resize(L, t, nasize, nsize);
}
static void rehash (lua_State *L, Table *t, const TValue *ek) {
int nasize, na;
- int nums[MAXBITS+1]; /* nums[i] = number of keys between 2^(i-1) and 2^i */
+ int nums[MAXBITS+1]; /* nums[i] = number of keys with 2^(i-1) < k <= 2^i */
int i;
int totaluse;
for (i=0; i<=MAXBITS; i++) nums[i] = 0; /* reset counts */
@@ -346,7 +347,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
/* compute new size for array part */
na = computesizes(nums, &nasize);
/* resize the table to new computed sizes */
- resize(L, t, nasize, totaluse - na);
+ luaH_resize(L, t, nasize, totaluse - na);
}
@@ -356,32 +357,28 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
*/
-Table *luaH_new (lua_State *L, int narray, int nhash) {
- Table *t = luaM_new(L, Table);
- luaC_link(L, obj2gco(t), LUA_TTABLE);
+Table *luaH_new (lua_State *L) {
+ Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;
t->metatable = NULL;
t->flags = cast_byte(~0);
- /* temporary values (kept only if some malloc fails) */
t->array = NULL;
t->sizearray = 0;
- t->lsizenode = 0;
- t->node = cast(Node *, dummynode);
- setarrayvector(L, t, narray);
- setnodevector(L, t, nhash);
+ setnodevector(L, t, 0);
return t;
}
void luaH_free (lua_State *L, Table *t) {
- if (t->node != dummynode)
- luaM_freearray(L, t->node, sizenode(t), Node);
- luaM_freearray(L, t->array, t->sizearray, TValue);
+ if (!isdummy(t->node))
+ luaM_freearray(L, t->node, cast(size_t, sizenode(t)));
+ luaM_freearray(L, t->array, t->sizearray);
luaM_free(L, t);
}
static Node *getfreepos (Table *t) {
- while (t->lastfree-- > t->node) {
+ while (t->lastfree > t->node) {
+ t->lastfree--;
if (ttisnil(gkey(t->lastfree)))
return t->lastfree;
}
@@ -391,23 +388,28 @@ static Node *getfreepos (Table *t) {
/*
-** inserts a new key into a hash table; first, check whether key's main
-** position is free. If not, check whether colliding node is in its main
-** position or not: if it is not, move colliding node to an empty place and
-** put new key in its main position; otherwise (colliding node is in its main
-** position), new key goes to an empty position.
+** inserts a new key into a hash table; first, check whether key's main
+** position is free. If not, check whether colliding node is in its main
+** position or not: if it is not, move colliding node to an empty place and
+** put new key in its main position; otherwise (colliding node is in its main
+** position), new key goes to an empty position.
*/
-static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
- Node *mp = mainposition(t, key);
- if (!ttisnil(gval(mp)) || mp == dummynode) {
+TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
+ Node *mp;
+ if (ttisnil(key)) luaG_runerror(L, "table index is nil");
+ else if (ttisnumber(key) && luai_numisnan(L, nvalue(key)))
+ luaG_runerror(L, "table index is NaN");
+ mp = mainposition(t, key);
+ if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
Node *n = getfreepos(t); /* get a free place */
if (n == NULL) { /* cannot find a free place? */
rehash(L, t, key); /* grow table */
- return luaH_set(L, t, key); /* re-insert key into grown table */
+ /* whatever called 'newkey' take care of TM cache and GC barrier */
+ return luaH_set(L, t, key); /* insert key into grown table */
}
- lua_assert(n != dummynode);
- othern = mainposition(t, key2tval(mp));
+ lua_assert(!isdummy(n));
+ othern = mainposition(t, gkey(mp));
if (othern != mp) { /* is colliding node out of its main position? */
/* yes; move colliding node into free position */
while (gnext(othern) != mp) othern = gnext(othern); /* find previous */
@@ -423,8 +425,8 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
mp = n;
}
}
- gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
- luaC_barriert(L, t, key);
+ setobj2t(L, gkey(mp), key);
+ luaC_barrierback(L, obj2gco(t), key);
lua_assert(ttisnil(gval(mp)));
return gval(mp);
}
@@ -433,7 +435,7 @@ static TValue *newkey (lua_State *L, Table *t, const TValue *key) {
/*
** search function for integers
*/
-const TValue *luaH_getnum (Table *t, int key) {
+const TValue *luaH_getint (Table *t, int key) {
/* (1 <= key && key <= t->sizearray) */
if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
return &t->array[key-1];
@@ -456,7 +458,7 @@ const TValue *luaH_getnum (Table *t, int key) {
const TValue *luaH_getstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
do { /* check whether `key' is somewhere in the chain */
- if (ttisstring(gkey(n)) && rawtsvalue(gkey(n)) == key)
+ if (ttisstring(gkey(n)) && eqstr(rawtsvalue(gkey(n)), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
@@ -468,7 +470,7 @@ const TValue *luaH_getstr (Table *t, TString *key) {
** main search function
*/
const TValue *luaH_get (Table *t, const TValue *key) {
- switch (ttype(key)) {
+ switch (ttypenv(key)) {
case LUA_TNIL: return luaO_nilobject;
case LUA_TSTRING: return luaH_getstr(t, rawtsvalue(key));
case LUA_TNUMBER: {
@@ -476,13 +478,13 @@ const TValue *luaH_get (Table *t, const TValue *key) {
lua_Number n = nvalue(key);
lua_number2int(k, n);
if (luai_numeq(cast_num(k), nvalue(key))) /* index is int? */
- return luaH_getnum(t, k); /* use specialized version */
+ return luaH_getint(t, k); /* use specialized version */
/* else go through */
}
default: {
Node *n = mainposition(t, key);
do { /* check whether `key' is somewhere in the chain */
- if (luaO_rawequalObj(key2tval(n), key))
+ if (luaV_rawequalobj(gkey(n), key))
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
@@ -492,41 +494,29 @@ const TValue *luaH_get (Table *t, const TValue *key) {
}
+/*
+** beware: when using this function you probably need to check a GC
+** barrier and invalidate the TM cache.
+*/
TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
const TValue *p = luaH_get(t, key);
- t->flags = 0;
if (p != luaO_nilobject)
return cast(TValue *, p);
- else {
- if (ttisnil(key)) luaG_runerror(L, "table index is nil");
- else if (ttisnumber(key) && luai_numisnan(nvalue(key)))
- luaG_runerror(L, "table index is NaN");
- return newkey(L, t, key);
- }
+ else return luaH_newkey(L, t, key);
}
-TValue *luaH_setnum (lua_State *L, Table *t, int key) {
- const TValue *p = luaH_getnum(t, key);
+void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
+ const TValue *p = luaH_getint(t, key);
+ TValue *cell;
if (p != luaO_nilobject)
- return cast(TValue *, p);
+ cell = cast(TValue *, p);
else {
TValue k;
setnvalue(&k, cast_num(key));
- return newkey(L, t, &k);
- }
-}
-
-
-TValue *luaH_setstr (lua_State *L, Table *t, TString *key) {
- const TValue *p = luaH_getstr(t, key);
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- TValue k;
- setsvalue(L, &k, key);
- return newkey(L, t, &k);
+ cell = luaH_newkey(L, t, &k);
}
+ setobj2t(L, cell, value);
}
@@ -534,20 +524,20 @@ static int unbound_search (Table *t, unsigned int j) {
unsigned int i = j; /* i is zero or a present index */
j++;
/* find `i' and `j' such that i is present and j is not */
- while (!ttisnil(luaH_getnum(t, j))) {
+ while (!ttisnil(luaH_getint(t, j))) {
i = j;
j *= 2;
if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
- while (!ttisnil(luaH_getnum(t, i))) i++;
+ while (!ttisnil(luaH_getint(t, i))) i++;
return i - 1;
}
}
/* now do a binary search between them */
while (j - i > 1) {
unsigned int m = (i+j)/2;
- if (ttisnil(luaH_getnum(t, m))) j = m;
+ if (ttisnil(luaH_getint(t, m))) j = m;
else i = m;
}
return i;
@@ -571,7 +561,7 @@ int luaH_getn (Table *t) {
return i;
}
/* else must find a boundary in hash part */
- else if (t->node == dummynode) /* hash part is empty? */
+ else if (isdummy(t->node)) /* hash part is empty? */
return j; /* that is easy... */
else return unbound_search(t, j);
}
@@ -584,6 +574,6 @@ Node *luaH_mainposition (const Table *t, const TValue *key) {
return mainposition(t, key);
}
-int luaH_isdummy (Node *n) { return n == dummynode; }
+int luaH_isdummy (Node *n) { return isdummy(n); }
#endif
diff --git a/l2detect/lua/ltable.h b/l2detect/lua/ltable.h
index f5b9d5e..2f6f5c2 100644
--- a/l2detect/lua/ltable.h
+++ b/l2detect/lua/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.10.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -11,20 +11,21 @@
#define gnode(t,i) (&(t)->node[i])
-#define gkey(n) (&(n)->i_key.nk)
+#define gkey(n) (&(n)->i_key.tvk)
#define gval(n) (&(n)->i_val)
#define gnext(n) ((n)->i_key.nk.next)
-#define key2tval(n) (&(n)->i_key.tvk)
+#define invalidateTMcache(t) ((t)->flags = 0)
-LUAI_FUNC const TValue *luaH_getnum (Table *t, int key);
-LUAI_FUNC TValue *luaH_setnum (lua_State *L, Table *t, int key);
+LUAI_FUNC const TValue *luaH_getint (Table *t, int key);
+LUAI_FUNC void luaH_setint (lua_State *L, Table *t, int key, TValue *value);
LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
-LUAI_FUNC TValue *luaH_setstr (lua_State *L, Table *t, TString *key);
LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
+LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);
LUAI_FUNC TValue *luaH_set (lua_State *L, Table *t, const TValue *key);
-LUAI_FUNC Table *luaH_new (lua_State *L, int narray, int lnhash);
+LUAI_FUNC Table *luaH_new (lua_State *L);
+LUAI_FUNC void luaH_resize (lua_State *L, Table *t, int nasize, int nhsize);
LUAI_FUNC void luaH_resizearray (lua_State *L, Table *t, int nasize);
LUAI_FUNC void luaH_free (lua_State *L, Table *t);
LUAI_FUNC int luaH_next (lua_State *L, Table *t, StkId key);
diff --git a/l2detect/lua/ltablib.c b/l2detect/lua/ltablib.c
index 4976783..52ce2bd 100644
--- a/l2detect/lua/ltablib.c
+++ b/l2detect/lua/ltablib.c
@@ -1,12 +1,11 @@
/*
-** $Id: ltablib.c,v 1.38.1.3 2008/02/14 16:46:58 roberto Exp $
+** $Id: ltablib.c,v 1.63 2011/11/28 17:26:30 roberto Exp $
** Library for Table Manipulation
** See Copyright Notice in lua.h
*/
-
-//#include
#include "stdafx.h"
+//#include
#define ltablib_c
#define LUA_LIB
@@ -17,43 +16,11 @@
#include "lualib.h"
-#define aux_getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
-
-
-static int foreachi (lua_State *L) {
- int i;
- int n = aux_getn(L, 1);
- luaL_checktype(L, 2, LUA_TFUNCTION);
- for (i=1; i <= n; i++) {
- lua_pushvalue(L, 2); /* function */
- lua_pushinteger(L, i); /* 1st argument */
- lua_rawgeti(L, 1, i); /* 2nd argument */
- lua_call(L, 2, 1);
- if (!lua_isnil(L, -1))
- return 1;
- lua_pop(L, 1); /* remove nil result */
- }
- return 0;
-}
-
-
-static int foreach (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
- luaL_checktype(L, 2, LUA_TFUNCTION);
- lua_pushnil(L); /* first key */
- while (lua_next(L, 1)) {
- lua_pushvalue(L, 2); /* function */
- lua_pushvalue(L, -3); /* key */
- lua_pushvalue(L, -3); /* value */
- lua_call(L, 2, 1);
- if (!lua_isnil(L, -1))
- return 1;
- lua_pop(L, 2); /* remove value and result */
- }
- return 0;
-}
+#define aux_getn(L,n) \
+ (luaL_checktype(L, n, LUA_TTABLE), luaL_len(L, n))
+#if defined(LUA_COMPAT_MAXN)
static int maxn (lua_State *L) {
lua_Number max = 0;
luaL_checktype(L, 1, LUA_TTABLE);
@@ -68,24 +35,7 @@ static int maxn (lua_State *L) {
lua_pushnumber(L, max);
return 1;
}
-
-
-static int getn (lua_State *L) {
- lua_pushinteger(L, aux_getn(L, 1));
- return 1;
-}
-
-
-static int setn (lua_State *L) {
- luaL_checktype(L, 1, LUA_TTABLE);
-#ifndef luaL_setn
- luaL_setn(L, 1, luaL_checkint(L, 2));
-#else
- luaL_error(L, LUA_QL("setn") " is obsolete");
#endif
- lua_pushvalue(L, 1);
- return 1;
-}
static int tinsert (lua_State *L) {
@@ -110,7 +60,6 @@ static int tinsert (lua_State *L) {
return luaL_error(L, "wrong number of arguments to " LUA_QL("insert"));
}
}
- luaL_setn(L, 1, e); /* new size */
lua_rawseti(L, 1, pos); /* t[pos] = v */
return 0;
}
@@ -120,8 +69,7 @@ static int tremove (lua_State *L) {
int e = aux_getn(L, 1);
int pos = luaL_optint(L, 2, e);
if (!(1 <= pos && pos <= e)) /* position is outside bounds? */
- return 0; /* nothing to remove */
- luaL_setn(L, 1, e - 1); /* t.n = n-1 */
+ return 0; /* nothing to remove */
lua_rawgeti(L, 1, pos); /* result = t[pos] */
for ( ;pos 0) { /* at least one element? */
+ int i;
+ lua_pushvalue(L, 1);
+ lua_rawseti(L, -2, 1); /* insert first element */
+ lua_replace(L, 1); /* move table into index 1 */
+ for (i = n; i >= 2; i--) /* assign other elements */
+ lua_rawseti(L, 1, i);
+ }
+ return 1; /* return table */
+}
+
+
+static int unpack (lua_State *L) {
+ int i, e, n;
+ luaL_checktype(L, 1, LUA_TTABLE);
+ i = luaL_optint(L, 2, 1);
+ e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));
+ if (i > e) return 0; /* empty range */
+ n = e - i + 1; /* number of elements */
+ if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */
+ return luaL_error(L, "too many results to unpack");
+ lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
+ while (i++ < e) /* push arg[i + 1...e] */
+ lua_rawgeti(L, 1, i);
+ return n;
+}
+
+/* }====================================================== */
+
+
/*
** {======================================================
** Quicksort
** (based on `Algorithms in MODULA-3', Robert Sedgewick;
** Addison-Wesley, 1993.)
+** =======================================================
*/
@@ -188,7 +178,7 @@ static int sort_comp (lua_State *L, int a, int b) {
return res;
}
else /* a < b? */
- return lua_lessthan(L, a, b);
+ return lua_compare(L, a, b, LUA_OPLT);
}
static void auxsort (lua_State *L, int l, int u) {
@@ -225,12 +215,12 @@ static void auxsort (lua_State *L, int l, int u) {
for (;;) { /* invariant: a[l..i] <= P <= a[j..u] */
/* repeat ++i until a[i] >= P */
while (lua_rawgeti(L, 1, ++i), sort_comp(L, -1, -2)) {
- if (i>u) luaL_error(L, "invalid order function for sorting");
+ if (i>=u) luaL_error(L, "invalid order function for sorting");
lua_pop(L, 1); /* remove a[i] */
}
/* repeat --j until a[j] <= P */
while (lua_rawgeti(L, 1, --j), sort_comp(L, -3, -1)) {
- if (j
#include "stdafx.h"
+//#include
#define ltm_c
#define LUA_CORE
@@ -20,20 +19,22 @@
#include "ltm.h"
+static const char udatatypename[] = "userdata";
-const char *const luaT_typenames[] = {
- "nil", "boolean", "userdata", "number",
- "string", "table", "function", "userdata", "thread",
- "proto", "upval"
+LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = {
+ "no value",
+ "nil", "boolean", udatatypename, "number",
+ "string", "table", "function", udatatypename, "thread",
+ "proto", "upval" /* these last two cases are used for tests only */
};
void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
- "__gc", "__mode", "__eq",
+ "__gc", "__mode", "__len", "__eq",
"__add", "__sub", "__mul", "__div", "__mod",
- "__pow", "__unm", "__len", "__lt", "__le",
+ "__pow", "__unm", "__lt", "__le",
"__concat", "__call"
};
int i;
@@ -61,7 +62,7 @@ const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
Table *mt;
- switch (ttype(o)) {
+ switch (ttypenv(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
@@ -69,7 +70,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
mt = uvalue(o)->metatable;
break;
default:
- mt = G(L)->mt[ttype(o)];
+ mt = G(L)->mt[ttypenv(o)];
}
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}
diff --git a/l2detect/lua/ltm.h b/l2detect/lua/ltm.h
index 64343b7..89bdc19 100644
--- a/l2detect/lua/ltm.h
+++ b/l2detect/lua/ltm.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.h,v 2.6.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: ltm.h,v 2.11 2011/02/28 17:32:10 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -20,6 +20,7 @@ typedef enum {
TM_NEWINDEX,
TM_GC,
TM_MODE,
+ TM_LEN,
TM_EQ, /* last tag method with `fast' access */
TM_ADD,
TM_SUB,
@@ -28,7 +29,6 @@ typedef enum {
TM_MOD,
TM_POW,
TM_UNM,
- TM_LEN,
TM_LT,
TM_LE,
TM_CONCAT,
@@ -43,7 +43,10 @@ typedef enum {
#define fasttm(l,et,e) gfasttm(G(l), et, e)
-LUAI_DATA const char *const luaT_typenames[];
+#define ttypename(x) luaT_typenames_[(x) + 1]
+#define objtypename(x) ttypename(ttypenv(x))
+
+LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
LUAI_FUNC const TValue *luaT_gettm (Table *events, TMS event, TString *ename);
diff --git a/l2detect/lua/lua.h b/l2detect/lua/lua.h
index e4bdfd3..1fafa45 100644
--- a/l2detect/lua/lua.h
+++ b/l2detect/lua/lua.h
@@ -1,6 +1,6 @@
/*
-** $Id: lua.h,v 1.218.1.5 2008/08/06 13:30:12 roberto Exp $
-** Lua - An Extensible Extension Language
+** $Id: lua.h,v 1.282 2011/11/29 15:55:08 roberto Exp $
+** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
*/
@@ -16,35 +16,39 @@
#include "luaconf.h"
-#define LUA_VERSION "Lua 5.1"
-#define LUA_RELEASE "Lua 5.1.4"
-#define LUA_VERSION_NUM 501
-#define LUA_COPYRIGHT "Copyright (C) 1994-2008 Lua.org, PUC-Rio"
-#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo & W. Celes"
+#define LUA_VERSION_MAJOR "5"
+#define LUA_VERSION_MINOR "2"
+#define LUA_VERSION_NUM 502
+#define LUA_VERSION_RELEASE "0"
+
+#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
+#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
+#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2011 Lua.org, PUC-Rio"
+#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
-/* mark for precompiled code (`Lua') */
-#define LUA_SIGNATURE "\033Lua"
+/* mark for precompiled code ('Lua') */
+#define LUA_SIGNATURE "\033Lua"
-/* option for multiple returns in `lua_pcall' and `lua_call' */
+/* option for multiple returns in 'lua_pcall' and 'lua_call' */
#define LUA_MULTRET (-1)
/*
** pseudo-indices
*/
-#define LUA_REGISTRYINDEX (-10000)
-#define LUA_ENVIRONINDEX (-10001)
-#define LUA_GLOBALSINDEX (-10002)
-#define lua_upvalueindex(i) (LUA_GLOBALSINDEX-(i))
+#define LUA_REGISTRYINDEX LUAI_FIRSTPSEUDOIDX
+#define lua_upvalueindex(i) (LUA_REGISTRYINDEX - (i))
-/* thread status; 0 is OK */
+/* thread status */
+#define LUA_OK 0
#define LUA_YIELD 1
#define LUA_ERRRUN 2
#define LUA_ERRSYNTAX 3
#define LUA_ERRMEM 4
-#define LUA_ERRERR 5
+#define LUA_ERRGCMM 5
+#define LUA_ERRERR 6
typedef struct lua_State lua_State;
@@ -81,18 +85,18 @@ typedef void * (*lua_Alloc) (void *ud, void *ptr, size_t osize, size_t nsize);
#define LUA_TUSERDATA 7
#define LUA_TTHREAD 8
+#define LUA_NUMTAGS 9
+
/* minimum Lua stack available to a C function */
#define LUA_MINSTACK 20
-/*
-** generic extra include file
-*/
-#if defined(LUA_USER_H)
-#include LUA_USER_H
-#endif
+/* predefined values in the registry */
+#define LUA_RIDX_MAINTHREAD 1
+#define LUA_RIDX_GLOBALS 2
+#define LUA_RIDX_LAST LUA_RIDX_GLOBALS
/* type of numbers in Lua */
@@ -102,6 +106,18 @@ typedef LUA_NUMBER lua_Number;
/* type for integer functions */
typedef LUA_INTEGER lua_Integer;
+/* unsigned integer type */
+typedef LUA_UNSIGNED lua_Unsigned;
+
+
+
+/*
+** generic extra include file
+*/
+#if defined(LUA_USER_H)
+#include LUA_USER_H
+#endif
+
/*
@@ -114,15 +130,20 @@ LUA_API lua_State *(lua_newthread) (lua_State *L);
LUA_API lua_CFunction (lua_atpanic) (lua_State *L, lua_CFunction panicf);
+LUA_API const lua_Number *(lua_version) (lua_State *L);
+
+
/*
** basic stack manipulation
*/
+LUA_API int (lua_absindex) (lua_State *L, int idx);
LUA_API int (lua_gettop) (lua_State *L);
LUA_API void (lua_settop) (lua_State *L, int idx);
LUA_API void (lua_pushvalue) (lua_State *L, int idx);
LUA_API void (lua_remove) (lua_State *L, int idx);
LUA_API void (lua_insert) (lua_State *L, int idx);
LUA_API void (lua_replace) (lua_State *L, int idx);
+LUA_API void (lua_copy) (lua_State *L, int fromidx, int toidx);
LUA_API int (lua_checkstack) (lua_State *L, int sz);
LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
@@ -139,29 +160,49 @@ LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);
-LUA_API int (lua_equal) (lua_State *L, int idx1, int idx2);
-LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
-LUA_API int (lua_lessthan) (lua_State *L, int idx1, int idx2);
-
-LUA_API lua_Number (lua_tonumber) (lua_State *L, int idx);
-LUA_API lua_Integer (lua_tointeger) (lua_State *L, int idx);
+LUA_API lua_Number (lua_tonumberx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Integer (lua_tointegerx) (lua_State *L, int idx, int *isnum);
+LUA_API lua_Unsigned (lua_tounsignedx) (lua_State *L, int idx, int *isnum);
LUA_API int (lua_toboolean) (lua_State *L, int idx);
LUA_API const char *(lua_tolstring) (lua_State *L, int idx, size_t *len);
-LUA_API size_t (lua_objlen) (lua_State *L, int idx);
+LUA_API size_t (lua_rawlen) (lua_State *L, int idx);
LUA_API lua_CFunction (lua_tocfunction) (lua_State *L, int idx);
LUA_API void *(lua_touserdata) (lua_State *L, int idx);
LUA_API lua_State *(lua_tothread) (lua_State *L, int idx);
LUA_API const void *(lua_topointer) (lua_State *L, int idx);
+/*
+** Comparison and arithmetic functions
+*/
+
+#define LUA_OPADD 0 /* ORDER TM */
+#define LUA_OPSUB 1
+#define LUA_OPMUL 2
+#define LUA_OPDIV 3
+#define LUA_OPMOD 4
+#define LUA_OPPOW 5
+#define LUA_OPUNM 6
+
+LUA_API void (lua_arith) (lua_State *L, int op);
+
+#define LUA_OPEQ 0
+#define LUA_OPLT 1
+#define LUA_OPLE 2
+
+LUA_API int (lua_rawequal) (lua_State *L, int idx1, int idx2);
+LUA_API int (lua_compare) (lua_State *L, int idx1, int idx2, int op);
+
+
/*
** push functions (C -> stack)
*/
-LUA_API void (lua_pushnil) (lua_State *L);
-LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
-LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
-LUA_API void (lua_pushlstring) (lua_State *L, const char *s, size_t l);
-LUA_API void (lua_pushstring) (lua_State *L, const char *s);
+LUA_API void (lua_pushnil) (lua_State *L);
+LUA_API void (lua_pushnumber) (lua_State *L, lua_Number n);
+LUA_API void (lua_pushinteger) (lua_State *L, lua_Integer n);
+LUA_API void (lua_pushunsigned) (lua_State *L, lua_Unsigned n);
+LUA_API const char *(lua_pushlstring) (lua_State *L, const char *s, size_t l);
+LUA_API const char *(lua_pushstring) (lua_State *L, const char *s);
LUA_API const char *(lua_pushvfstring) (lua_State *L, const char *fmt,
va_list argp);
LUA_API const char *(lua_pushfstring) (lua_State *L, const char *fmt, ...);
@@ -174,35 +215,47 @@ LUA_API int (lua_pushthread) (lua_State *L);
/*
** get functions (Lua -> stack)
*/
+LUA_API void (lua_getglobal) (lua_State *L, const char *var);
LUA_API void (lua_gettable) (lua_State *L, int idx);
LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawget) (lua_State *L, int idx);
LUA_API void (lua_rawgeti) (lua_State *L, int idx, int n);
+LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p);
LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
-LUA_API void (lua_getfenv) (lua_State *L, int idx);
+LUA_API void (lua_getuservalue) (lua_State *L, int idx);
/*
** set functions (stack -> Lua)
*/
+LUA_API void (lua_setglobal) (lua_State *L, const char *var);
LUA_API void (lua_settable) (lua_State *L, int idx);
LUA_API void (lua_setfield) (lua_State *L, int idx, const char *k);
LUA_API void (lua_rawset) (lua_State *L, int idx);
LUA_API void (lua_rawseti) (lua_State *L, int idx, int n);
+LUA_API void (lua_rawsetp) (lua_State *L, int idx, const void *p);
LUA_API int (lua_setmetatable) (lua_State *L, int objindex);
-LUA_API int (lua_setfenv) (lua_State *L, int idx);
+LUA_API void (lua_setuservalue) (lua_State *L, int idx);
/*
-** `load' and `call' functions (load and run Lua code)
+** 'load' and 'call' functions (load and run Lua code)
*/
-LUA_API void (lua_call) (lua_State *L, int nargs, int nresults);
-LUA_API int (lua_pcall) (lua_State *L, int nargs, int nresults, int errfunc);
-LUA_API int (lua_cpcall) (lua_State *L, lua_CFunction func, void *ud);
+LUA_API void (lua_callk) (lua_State *L, int nargs, int nresults, int ctx,
+ lua_CFunction k);
+#define lua_call(L,n,r) lua_callk(L, (n), (r), 0, NULL)
+
+LUA_API int (lua_getctx) (lua_State *L, int *ctx);
+
+LUA_API int (lua_pcallk) (lua_State *L, int nargs, int nresults, int errfunc,
+ int ctx, lua_CFunction k);
+#define lua_pcall(L,n,r,f) lua_pcallk(L, (n), (r), (f), 0, NULL)
+
LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt,
- const char *chunkname);
+ const char *chunkname,
+ const char *mode);
LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
@@ -210,8 +263,10 @@ LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);
/*
** coroutine functions
*/
-LUA_API int (lua_yield) (lua_State *L, int nresults);
-LUA_API int (lua_resume) (lua_State *L, int narg);
+LUA_API int (lua_yieldk) (lua_State *L, int nresults, int ctx,
+ lua_CFunction k);
+#define lua_yield(L,n) lua_yieldk(L, (n), 0, NULL)
+LUA_API int (lua_resume) (lua_State *L, lua_State *from, int narg);
LUA_API int (lua_status) (lua_State *L);
/*
@@ -226,6 +281,10 @@ LUA_API int (lua_status) (lua_State *L);
#define LUA_GCSTEP 5
#define LUA_GCSETPAUSE 6
#define LUA_GCSETSTEPMUL 7
+#define LUA_GCSETMAJORINC 8
+#define LUA_GCISRUNNING 9
+#define LUA_GCGEN 10
+#define LUA_GCINC 11
LUA_API int (lua_gc) (lua_State *L, int what, int data);
@@ -239,18 +298,23 @@ LUA_API int (lua_error) (lua_State *L);
LUA_API int (lua_next) (lua_State *L, int idx);
LUA_API void (lua_concat) (lua_State *L, int n);
+LUA_API void (lua_len) (lua_State *L, int idx);
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
-LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
+LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
-/*
+/*
** ===============================================================
** some useful macros
** ===============================================================
*/
+#define lua_tonumber(L,i) lua_tonumberx(L,i,NULL)
+#define lua_tointeger(L,i) lua_tointegerx(L,i,NULL)
+#define lua_tounsigned(L,i) lua_tounsignedx(L,i,NULL)
+
#define lua_pop(L,n) lua_settop(L, -(n)-1)
#define lua_newtable(L) lua_createtable(L, 0, 0)
@@ -259,8 +323,6 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_pushcfunction(L,f) lua_pushcclosure(L, (f), 0)
-#define lua_strlen(L,i) lua_objlen(L, (i))
-
#define lua_isfunction(L,n) (lua_type(L, (n)) == LUA_TFUNCTION)
#define lua_istable(L,n) (lua_type(L, (n)) == LUA_TTABLE)
#define lua_islightuserdata(L,n) (lua_type(L, (n)) == LUA_TLIGHTUSERDATA)
@@ -273,31 +335,13 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud);
#define lua_pushliteral(L, s) \
lua_pushlstring(L, "" s, (sizeof(s)/sizeof(char))-1)
-#define lua_setglobal(L,s) lua_setfield(L, LUA_GLOBALSINDEX, (s))
-#define lua_getglobal(L,s) lua_getfield(L, LUA_GLOBALSINDEX, (s))
+#define lua_pushglobaltable(L) \
+ lua_rawgeti(L, LUA_REGISTRYINDEX, LUA_RIDX_GLOBALS)
#define lua_tostring(L,i) lua_tolstring(L, (i), NULL)
-/*
-** compatibility macros and functions
-*/
-
-#define lua_open() luaL_newstate()
-
-#define lua_getregistry(L) lua_pushvalue(L, LUA_REGISTRYINDEX)
-
-#define lua_getgccount(L) lua_gc(L, LUA_GCCOUNT, 0)
-
-#define lua_Chunkreader lua_Reader
-#define lua_Chunkwriter lua_Writer
-
-
-/* hack */
-LUA_API void lua_setlevel (lua_State *from, lua_State *to);
-
-
/*
** {======================================================================
** Debug API
@@ -312,7 +356,7 @@ LUA_API void lua_setlevel (lua_State *from, lua_State *to);
#define LUA_HOOKRET 1
#define LUA_HOOKLINE 2
#define LUA_HOOKCOUNT 3
-#define LUA_HOOKTAILRET 4
+#define LUA_HOOKTAILCALL 4
/*
@@ -326,43 +370,50 @@ LUA_API void lua_setlevel (lua_State *from, lua_State *to);
typedef struct lua_Debug lua_Debug; /* activation record */
-/* Functions to be called by the debuger in specific events */
+/* Functions to be called by the debugger in specific events */
typedef void (*lua_Hook) (lua_State *L, lua_Debug *ar);
-LUA_API int lua_getstack (lua_State *L, int level, lua_Debug *ar);
-LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar);
-LUA_API const char *lua_getlocal (lua_State *L, const lua_Debug *ar, int n);
-LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n);
-LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n);
-LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n);
+LUA_API int (lua_getstack) (lua_State *L, int level, lua_Debug *ar);
+LUA_API int (lua_getinfo) (lua_State *L, const char *what, lua_Debug *ar);
+LUA_API const char *(lua_getlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_setlocal) (lua_State *L, const lua_Debug *ar, int n);
+LUA_API const char *(lua_getupvalue) (lua_State *L, int funcindex, int n);
+LUA_API const char *(lua_setupvalue) (lua_State *L, int funcindex, int n);
-LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count);
-LUA_API lua_Hook lua_gethook (lua_State *L);
-LUA_API int lua_gethookmask (lua_State *L);
-LUA_API int lua_gethookcount (lua_State *L);
+LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n);
+LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
+ int fidx2, int n2);
+
+LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
+LUA_API lua_Hook (lua_gethook) (lua_State *L);
+LUA_API int (lua_gethookmask) (lua_State *L);
+LUA_API int (lua_gethookcount) (lua_State *L);
struct lua_Debug {
int event;
const char *name; /* (n) */
- const char *namewhat; /* (n) `global', `local', `field', `method' */
- const char *what; /* (S) `Lua', `C', `main', `tail' */
+ const char *namewhat; /* (n) 'global', 'local', 'field', 'method' */
+ const char *what; /* (S) 'Lua', 'C', 'main', 'tail' */
const char *source; /* (S) */
int currentline; /* (l) */
- int nups; /* (u) number of upvalues */
int linedefined; /* (S) */
int lastlinedefined; /* (S) */
+ unsigned char nups; /* (u) number of upvalues */
+ unsigned char nparams;/* (u) number of parameters */
+ char isvararg; /* (u) */
+ char istailcall; /* (t) */
char short_src[LUA_IDSIZE]; /* (S) */
/* private part */
- int i_ci; /* active function */
+ struct CallInfo *i_ci; /* active function */
};
/* }====================================================================== */
/******************************************************************************
-* Copyright (C) 1994-2008 Lua.org, PUC-Rio. All rights reserved.
+* Copyright (C) 1994-2011 Lua.org, PUC-Rio. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
diff --git a/l2detect/lua/luaconf.h b/l2detect/lua/luaconf.h
index 8b2b4ca..bab401e 100644
--- a/l2detect/lua/luaconf.h
+++ b/l2detect/lua/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.82.1.7 2008/02/11 16:25:08 roberto Exp $
+** $Id: luaconf.h,v 1.170 2011/12/06 16:58:36 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -24,30 +24,44 @@
** CHANGE it (define it) if you want Lua to avoid the use of any
** non-ansi feature or library.
*/
-#if defined(__STRICT_ANSI__)
+#if !defined(LUA_ANSI) && defined(__STRICT_ANSI__)
#define LUA_ANSI
#endif
-#if !defined(LUA_ANSI) && defined(_WIN32)
-#define LUA_WIN
+#if !defined(LUA_ANSI) && defined(_WIN32) && !defined(_WIN32_WCE)
+#define LUA_WIN /* enable goodies for regular Windows platforms */
#endif
+#if defined(LUA_WIN)
+#define LUA_DL_DLL
+#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
+#endif
+
+
+
#if defined(LUA_USE_LINUX)
#define LUA_USE_POSIX
#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
#define LUA_USE_READLINE /* needs some extra libraries */
+#define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */
+#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
+#define LUA_USE_LONGLONG /* assume support for long long */
#endif
#if defined(LUA_USE_MACOSX)
#define LUA_USE_POSIX
-#define LUA_DL_DYLD /* does not need extra library */
+#define LUA_USE_DLOPEN /* does not need -ldl */
+#define LUA_USE_READLINE /* needs an extra library: -lreadline */
+#define LUA_USE_STRTODHEX /* assume 'strtod' handles hexa formats */
+#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
+#define LUA_USE_LONGLONG /* assume support for long long */
#endif
/*
-@@ LUA_USE_POSIX includes all functionallity listed as X/Open System
+@@ LUA_USE_POSIX includes all functionality listed as X/Open System
@* Interfaces Extension (XSI).
** CHANGE it (define it) if your system is XSI compatible.
*/
@@ -56,20 +70,10 @@
#define LUA_USE_ISATTY
#define LUA_USE_POPEN
#define LUA_USE_ULONGJMP
+#define LUA_USE_GMTIME_R
#endif
-/*
-@@ LUA_PATH and LUA_CPATH are the names of the environment variables that
-@* Lua check to set its paths.
-@@ LUA_INIT is the name of the environment variable that Lua
-@* checks for initialization code.
-** CHANGE them if you want different names.
-*/
-#define LUA_PATH "LUA_PATH"
-#define LUA_CPATH "LUA_CPATH"
-#define LUA_INIT "LUA_INIT"
-
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
@@ -80,7 +84,7 @@
** hierarchy or if you want to install your libraries in
** non-conventional directories.
*/
-#if defined(_WIN32)
+#if defined(_WIN32) /* { */
/*
** In Windows, any exclamation mark ('!') in the path is replaced by the
** path of the directory of the executable file of the current process.
@@ -88,21 +92,23 @@
#define LUA_LDIR "!\\lua\\"
#define LUA_CDIR "!\\"
#define LUA_PATH_DEFAULT \
- ".\\?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
- LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua"
+ LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua"
#define LUA_CPATH_DEFAULT \
- ".\\?.dll;" LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll"
+ LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
-#else
+#else /* }{ */
+
+#define LUA_VDIR LUA_VERSION_MAJOR "." LUA_VERSION_MINOR "/"
#define LUA_ROOT "/usr/local/"
-#define LUA_LDIR LUA_ROOT "share/lua/5.1/"
-#define LUA_CDIR LUA_ROOT "lib/lua/5.1/"
+#define LUA_LDIR LUA_ROOT "share/lua/" LUA_VDIR
+#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR
#define LUA_PATH_DEFAULT \
- "./?.lua;" LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
- LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua"
+ LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
+ LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua"
#define LUA_CPATH_DEFAULT \
- "./?.so;" LUA_CDIR"?.so;" LUA_CDIR"loadall.so"
-#endif
+ LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
+#endif /* } */
/*
@@ -118,79 +124,67 @@
/*
-@@ LUA_PATHSEP is the character that separates templates in a path.
-@@ LUA_PATH_MARK is the string that marks the substitution points in a
-@* template.
-@@ LUA_EXECDIR in a Windows path is replaced by the executable's
-@* directory.
-@@ LUA_IGMARK is a mark to ignore all before it when bulding the
-@* luaopen_ function name.
-** CHANGE them if for some reason your system cannot use those
-** characters. (E.g., if one of those characters is a common character
-** in file/directory names.) Probably you do not need to change them.
+@@ LUA_ENV is the name of the variable that holds the current
+@@ environment, used to access global names.
+** CHANGE it if you do not like this name.
*/
-#define LUA_PATHSEP ";"
-#define LUA_PATH_MARK "?"
-#define LUA_EXECDIR "!"
-#define LUA_IGMARK "-"
-
-
-/*
-@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
-** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
-** machines, ptrdiff_t gives a good choice between int or long.)
-*/
-#define LUA_INTEGER ptrdiff_t
+#define LUA_ENV "_ENV"
/*
@@ LUA_API is a mark for all core API functions.
-@@ LUALIB_API is a mark for all standard library functions.
+@@ LUALIB_API is a mark for all auxiliary library functions.
+@@ LUAMOD_API is a mark for all standard library opening functions.
** CHANGE them if you need to define those functions in some special way.
** For instance, if you want to create one Windows DLL with the core and
** the libraries, you may want to use the following definition (define
** LUA_BUILD_AS_DLL to get it).
*/
-#if defined(LUA_BUILD_AS_DLL)
+#if defined(LUA_BUILD_AS_DLL) /* { */
-#if defined(LUA_CORE) || defined(LUA_LIB)
+#if defined(LUA_CORE) || defined(LUA_LIB) /* { */
#define LUA_API __declspec(dllexport)
-#else
+#else /* }{ */
#define LUA_API __declspec(dllimport)
-#endif
+#endif /* } */
-#else
+#else /* }{ */
#define LUA_API extern
-#endif
+#endif /* } */
+
/* more often than not the libs go together with the core */
#define LUALIB_API LUA_API
+#define LUAMOD_API LUALIB_API
/*
@@ LUAI_FUNC is a mark for all extern functions that are not to be
@* exported to outside modules.
-@@ LUAI_DATA is a mark for all extern (const) variables that are not to
-@* be exported to outside modules.
+@@ LUAI_DDEF and LUAI_DDEC are marks for all extern (const) variables
+@* that are not to be exported to outside modules (LUAI_DDEF for
+@* definitions and LUAI_DDEC for declarations).
** CHANGE them if you need to mark them in some special way. Elf/gcc
** (versions 3.2 and later) mark them as "hidden" to optimize access
-** when Lua is compiled as a shared library.
+** when Lua is compiled as a shared library. Not all elf targets support
+** this attribute. Unfortunately, gcc does not offer a way to check
+** whether the target offers that support, and those without support
+** give a warning about it. To avoid these warnings, change to the
+** default definition.
*/
-#if defined(luaall_c)
-#define LUAI_FUNC static
-#define LUAI_DATA /* empty */
-
-#elif defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
- defined(__ELF__)
+#if defined(__GNUC__) && ((__GNUC__*100 + __GNUC_MINOR__) >= 302) && \
+ defined(__ELF__) /* { */
#define LUAI_FUNC __attribute__((visibility("hidden"))) extern
-#define LUAI_DATA LUAI_FUNC
+#define LUAI_DDEC LUAI_FUNC
+#define LUAI_DDEF /* empty */
-#else
+#else /* }{ */
#define LUAI_FUNC extern
-#define LUAI_DATA extern
-#endif
+#define LUAI_DDEC extern
+#define LUAI_DDEF /* empty */
+#endif /* } */
@@ -210,177 +204,103 @@
#define LUA_IDSIZE 60
+/*
+@@ luai_writestring/luai_writeline define how 'print' prints its results.
+** They are only used in libraries and the stand-alone program. (The #if
+** avoids including 'stdio.h' everywhere.)
+*/
+#if defined(LUA_LIB) || defined(lua_c)
+#include
+#define luai_writestring(s,l) fwrite((s), sizeof(char), (l), stdout)
+#define luai_writeline() (luai_writestring("\n", 1), fflush(stdout))
+#endif
+
+/*
+@@ luai_writestringerror defines how to print error messages.
+** (A format string with one argument is enough for Lua...)
+*/
+#define luai_writestringerror(s,p) \
+ (fprintf(stderr, (s), (p)), fflush(stderr))
+
+
+
+
+
/*
** {==================================================================
-** Stand-alone configuration
+** Compatibility with previous versions
** ===================================================================
*/
-#if defined(lua_c) || defined(luaall_c)
+/*
+@@ LUA_COMPAT_ALL controls all compatibility options.
+** You can define it to get all options, or change specific options
+** to fit your specific needs.
+*/
+#if defined(LUA_COMPAT_ALL) /* { */
/*
-@@ lua_stdin_is_tty detects whether the standard input is a 'tty' (that
-@* is, whether we're running lua interactively).
-** CHANGE it if you have a better definition for non-POSIX/non-Windows
-** systems.
+@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
+** You can replace it with 'table.unpack'.
*/
-#if defined(LUA_USE_ISATTY)
-#include
-#define lua_stdin_is_tty() isatty(0)
-#elif defined(LUA_WIN)
-#include
-#include
-#define lua_stdin_is_tty() _isatty(_fileno(stdin))
-#else
-#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
-#endif
+#define LUA_COMPAT_UNPACK
+
+/*
+@@ LUA_COMPAT_LOADERS controls the presence of table 'package.loaders'.
+** You can replace it with 'package.searchers'.
+*/
+#define LUA_COMPAT_LOADERS
+
+/*
+@@ macro 'lua_cpcall' emulates deprecated function lua_cpcall.
+** You can call your C function directly (with light C functions).
+*/
+#define lua_cpcall(L,f,u) \
+ (lua_pushcfunction(L, (f)), \
+ lua_pushlightuserdata(L,(u)), \
+ lua_pcall(L,1,0,0))
/*
-@@ LUA_PROMPT is the default prompt used by stand-alone Lua.
-@@ LUA_PROMPT2 is the default continuation prompt used by stand-alone Lua.
-** CHANGE them if you want different prompts. (You can also change the
-** prompts dynamically, assigning to globals _PROMPT/_PROMPT2.)
+@@ LUA_COMPAT_LOG10 defines the function 'log10' in the math library.
+** You can rewrite 'log10(x)' as 'log(x, 10)'.
*/
-#define LUA_PROMPT "> "
-#define LUA_PROMPT2 ">> "
-
+#define LUA_COMPAT_LOG10
/*
-@@ LUA_PROGNAME is the default name for the stand-alone Lua program.
-** CHANGE it if your stand-alone interpreter has a different name and
-** your system is not able to detect that name automatically.
+@@ LUA_COMPAT_LOADSTRING defines the function 'loadstring' in the base
+** library. You can rewrite 'loadstring(s)' as 'load(s)'.
*/
-#define LUA_PROGNAME "lua"
-
+#define LUA_COMPAT_LOADSTRING
/*
-@@ LUA_MAXINPUT is the maximum length for an input line in the
-@* stand-alone interpreter.
-** CHANGE it if you need longer lines.
+@@ LUA_COMPAT_MAXN defines the function 'maxn' in the table library.
*/
-#define LUA_MAXINPUT 512
-
+#define LUA_COMPAT_MAXN
/*
-@@ lua_readline defines how to show a prompt and then read a line from
-@* the standard input.
-@@ lua_saveline defines how to "save" a read line in a "history".
-@@ lua_freeline defines how to free a line read by lua_readline.
-** CHANGE them if you want to improve this functionality (e.g., by using
-** GNU readline and history facilities).
+@@ The following macros supply trivial compatibility for some
+** changes in the API. The macros themselves document how to
+** change your code to avoid using them.
*/
-#if defined(LUA_USE_READLINE)
-#include
-#include
-#include
-#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
-#define lua_saveline(L,idx) \
- if (lua_strlen(L,idx) > 0) /* non-empty line? */ \
- add_history(lua_tostring(L, idx)); /* add it to history */
-#define lua_freeline(L,b) ((void)L, free(b))
-#else
-#define lua_readline(L,b,p) \
- ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
- fgets(b, LUA_MAXINPUT, stdin) != NULL) /* get line */
-#define lua_saveline(L,idx) { (void)L; (void)idx; }
-#define lua_freeline(L,b) { (void)L; (void)b; }
-#endif
+#define lua_strlen(L,i) lua_rawlen(L, (i))
-#endif
+#define lua_objlen(L,i) lua_rawlen(L, (i))
+
+#define lua_equal(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPEQ)
+#define lua_lessthan(L,idx1,idx2) lua_compare(L,(idx1),(idx2),LUA_OPLT)
+
+/*
+@@ LUA_COMPAT_MODULE controls compatibility with previous
+** module functions 'module' (Lua) and 'luaL_register' (C).
+*/
+#define LUA_COMPAT_MODULE
+
+#endif /* } */
/* }================================================================== */
-/*
-@@ LUAI_GCPAUSE defines the default pause between garbage-collector cycles
-@* as a percentage.
-** CHANGE it if you want the GC to run faster or slower (higher values
-** mean larger pauses which mean slower collection.) You can also change
-** this value dynamically.
-*/
-#define LUAI_GCPAUSE 200 /* 200% (wait memory to double before next GC) */
-
-
-/*
-@@ LUAI_GCMUL defines the default speed of garbage collection relative to
-@* memory allocation as a percentage.
-** CHANGE it if you want to change the granularity of the garbage
-** collection. (Higher values mean coarser collections. 0 represents
-** infinity, where each step performs a full collection.) You can also
-** change this value dynamically.
-*/
-#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
-
-
-
-/*
-@@ LUA_COMPAT_GETN controls compatibility with old getn behavior.
-** CHANGE it (define it) if you want exact compatibility with the
-** behavior of setn/getn in Lua 5.0.
-*/
-#undef LUA_COMPAT_GETN
-
-/*
-@@ LUA_COMPAT_LOADLIB controls compatibility about global loadlib.
-** CHANGE it to undefined as soon as you do not need a global 'loadlib'
-** function (the function is still available as 'package.loadlib').
-*/
-#undef LUA_COMPAT_LOADLIB
-
-/*
-@@ LUA_COMPAT_VARARG controls compatibility with old vararg feature.
-** CHANGE it to undefined as soon as your programs use only '...' to
-** access vararg parameters (instead of the old 'arg' table).
-*/
-#define LUA_COMPAT_VARARG
-
-/*
-@@ LUA_COMPAT_MOD controls compatibility with old math.mod function.
-** CHANGE it to undefined as soon as your programs use 'math.fmod' or
-** the new '%' operator instead of 'math.mod'.
-*/
-#define LUA_COMPAT_MOD
-
-/*
-@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
-@* facility.
-** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
-** off the advisory error when nesting [[...]].
-*/
-#define LUA_COMPAT_LSTR 1
-
-/*
-@@ LUA_COMPAT_GFIND controls compatibility with old 'string.gfind' name.
-** CHANGE it to undefined as soon as you rename 'string.gfind' to
-** 'string.gmatch'.
-*/
-#define LUA_COMPAT_GFIND
-
-/*
-@@ LUA_COMPAT_OPENLIB controls compatibility with old 'luaL_openlib'
-@* behavior.
-** CHANGE it to undefined as soon as you replace to 'luaL_register'
-** your uses of 'luaL_openlib'
-*/
-#define LUA_COMPAT_OPENLIB
-
-
-
-/*
-@@ luai_apicheck is the assert macro used by the Lua-C API.
-** CHANGE luai_apicheck if you want Lua to perform some checks in the
-** parameters it gets from API calls. This may slow down the interpreter
-** a bit, but may be quite useful when debugging C code that interfaces
-** with Lua. A useful redefinition is to use assert.h.
-*/
-#if defined(LUA_USE_APICHECK)
-#include
-#define luai_apicheck(L,o) { (void)L; assert(o); }
-#else
-#define luai_apicheck(L,o) { (void)L; }
-#endif
-
/*
@@ LUAI_BITSINT defines the number of bits in an int.
@@ -388,107 +308,62 @@
** your machine. Probably you do not need to change this.
*/
/* avoid overflows in comparison */
-#if INT_MAX-20 < 32760
+#if INT_MAX-20 < 32760 /* { */
#define LUAI_BITSINT 16
-#elif INT_MAX > 2147483640L
+#elif INT_MAX > 2147483640L /* }{ */
/* int has at least 32 bits */
#define LUAI_BITSINT 32
-#else
+#else /* }{ */
#error "you must define LUA_BITSINT with number of bits in an integer"
-#endif
+#endif /* } */
/*
-@@ LUAI_UINT32 is an unsigned integer with at least 32 bits.
-@@ LUAI_INT32 is an signed integer with at least 32 bits.
+@@ LUA_INT32 is an signed integer with exactly 32 bits.
@@ LUAI_UMEM is an unsigned integer big enough to count the total
@* memory used by Lua.
@@ LUAI_MEM is a signed integer big enough to count the total memory
@* used by Lua.
** CHANGE here if for some weird reason the default definitions are not
-** good enough for your machine. (The definitions in the 'else'
-** part always works, but may waste space on machines with 64-bit
-** longs.) Probably you do not need to change this.
+** good enough for your machine. Probably you do not need to change
+** this.
*/
-#if LUAI_BITSINT >= 32
-#define LUAI_UINT32 unsigned int
-#define LUAI_INT32 int
-#define LUAI_MAXINT32 INT_MAX
+#if LUAI_BITSINT >= 32 /* { */
+#define LUA_INT32 int
#define LUAI_UMEM size_t
#define LUAI_MEM ptrdiff_t
-#else
+#else /* }{ */
/* 16-bit ints */
-#define LUAI_UINT32 unsigned long
-#define LUAI_INT32 long
-#define LUAI_MAXINT32 LONG_MAX
+#define LUA_INT32 long
#define LUAI_UMEM unsigned long
#define LUAI_MEM long
+#endif /* } */
+
+
+/*
+@@ LUAI_MAXSTACK limits the size of the Lua stack.
+** CHANGE it if you need a different limit. This limit is arbitrary;
+** its only purpose is to stop Lua to consume unlimited stack
+** space (and to reserve some numbers for pseudo-indices).
+*/
+#if LUAI_BITSINT >= 32
+#define LUAI_MAXSTACK 1000000
+#else
+#define LUAI_MAXSTACK 15000
#endif
-
-/*
-@@ LUAI_MAXCALLS limits the number of nested calls.
-** CHANGE it if you need really deep recursive calls. This limit is
-** arbitrary; its only purpose is to stop infinite recursion before
-** exhausting memory.
-*/
-#define LUAI_MAXCALLS 20000
+/* reserve some space for error handling */
+#define LUAI_FIRSTPSEUDOIDX (-LUAI_MAXSTACK - 1000)
-/*
-@@ LUAI_MAXCSTACK limits the number of Lua stack slots that a C function
-@* can use.
-** CHANGE it if you need lots of (Lua) stack space for your C
-** functions. This limit is arbitrary; its only purpose is to stop C
-** functions to consume unlimited stack space. (must be smaller than
-** -LUA_REGISTRYINDEX)
-*/
-#define LUAI_MAXCSTACK 8000
-
-
-
-/*
-** {==================================================================
-** CHANGE (to smaller values) the following definitions if your system
-** has a small C stack. (Or you may want to change them to larger
-** values if your system has a large C stack and these limits are
-** too rigid for you.) Some of these constants control the size of
-** stack-allocated arrays used by the compiler or the interpreter, while
-** others limit the maximum number of recursive calls that the compiler
-** or the interpreter can perform. Values too large may cause a C stack
-** overflow for some forms of deep constructs.
-** ===================================================================
-*/
-
-
-/*
-@@ LUAI_MAXCCALLS is the maximum depth for nested C calls (short) and
-@* syntactical nested non-terminals in a program.
-*/
-#define LUAI_MAXCCALLS 200
-
-
-/*
-@@ LUAI_MAXVARS is the maximum number of local variables per function
-@* (must be smaller than 250).
-*/
-#define LUAI_MAXVARS 200
-
-
-/*
-@@ LUAI_MAXUPVALUES is the maximum number of upvalues per function
-@* (must be smaller than 250).
-*/
-#define LUAI_MAXUPVALUES 60
/*
@@ LUAL_BUFFERSIZE is the buffer size used by the lauxlib buffer system.
+** CHANGE it if it uses too much C-stack space.
*/
#define LUAL_BUFFERSIZE BUFSIZ
-/* }================================================================== */
-
@@ -516,237 +391,128 @@
@@ LUA_NUMBER_FMT is the format for writing numbers.
@@ lua_number2str converts a number to a string.
@@ LUAI_MAXNUMBER2STR is maximum size of previous conversion.
-@@ lua_str2number converts a string to a number.
*/
#define LUA_NUMBER_SCAN "%lf"
#define LUA_NUMBER_FMT "%.14g"
#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
#define LUAI_MAXNUMBER2STR 32 /* 16 digits, sign, point, and \0 */
+
+
+/*
+@@ lua_str2number converts a decimal numeric string to a number.
+@@ lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' do both conversions. C89, however, has no function
+** to convert floating hexadecimal strings to numbers. For these
+** systems, you can leave 'lua_strx2number' undefined and Lua will
+** provide its own implementation.
+*/
#define lua_str2number(s,p) strtod((s), (p))
+#if defined(LUA_USE_STRTODHEX)
+#define lua_strx2number(s,p) strtod((s), (p))
+#endif
+
/*
@@ The luai_num* macros define the primitive operations over numbers.
*/
-#if defined(LUA_CORE)
-//#include
-#define luai_numadd(a,b) ((a)+(b))
-#define luai_numsub(a,b) ((a)-(b))
-#define luai_nummul(a,b) ((a)*(b))
-#define luai_numdiv(a,b) ((a)/(b))
-#define luai_nummod(a,b) ((a) - floor((a)/(b))*(b))
-#define luai_numpow(a,b) (pow(a,b))
-#define luai_numunm(a) (-(a))
-#define luai_numeq(a,b) ((a)==(b))
-#define luai_numlt(a,b) ((a)<(b))
-#define luai_numle(a,b) ((a)<=(b))
-#define luai_numisnan(a) (!luai_numeq((a), (a)))
+
+/* the following operations need the math library */
+#if defined(lobject_c) || defined(lvm_c)
+#include
+#define luai_nummod(L,a,b) ((a) - floor((a)/(b))*(b))
+#define luai_numpow(L,a,b) (pow(a,b))
#endif
+/* these are quite standard operations */
+#if defined(LUA_CORE)
+#define luai_numadd(L,a,b) ((a)+(b))
+#define luai_numsub(L,a,b) ((a)-(b))
+#define luai_nummul(L,a,b) ((a)*(b))
+#define luai_numdiv(L,a,b) ((a)/(b))
+#define luai_numunm(L,a) (-(a))
+#define luai_numeq(a,b) ((a)==(b))
+#define luai_numlt(L,a,b) ((a)<(b))
+#define luai_numle(L,a,b) ((a)<=(b))
+#define luai_numisnan(L,a) (!luai_numeq((a), (a)))
+#endif
+
+
/*
-@@ lua_number2int is a macro to convert lua_Number to int.
-@@ lua_number2integer is a macro to convert lua_Number to lua_Integer.
-** CHANGE them if you know a faster way to convert a lua_Number to
-** int (with any rounding method and without throwing errors) in your
-** system. In Pentium machines, a naive typecast from double to int
-** in C is extremely slow, so any alternative is worth trying.
+@@ LUA_INTEGER is the integral type used by lua_pushinteger/lua_tointeger.
+** CHANGE that if ptrdiff_t is not adequate on your machine. (On most
+** machines, ptrdiff_t gives a good choice between int or long.)
*/
+#define LUA_INTEGER ptrdiff_t
-/* On a Pentium, resort to a trick */
-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) && !defined(__SSE2__) && \
- (defined(__i386) || defined (_M_IX86) || defined(__i386__))
+/*
+@@ LUA_UNSIGNED is the integral type used by lua_pushunsigned/lua_tounsigned.
+** It must have at least 32 bits.
+*/
+#define LUA_UNSIGNED unsigned LUA_INT32
-/* On a Microsoft compiler, use assembler */
-#if defined(_MSC_VER)
-#define lua_number2int(i,d) __asm fld d __asm fistp i
-#define lua_number2integer(i,n) lua_number2int(i, n)
+#if defined(LUA_CORE) /* { */
-/* the next trick should work on any Pentium, but sometimes clashes
+#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
+
+/* On a Microsoft compiler on a Pentium, use assembler to avoid clashes
with a DirectX idiosyncrasy */
-#else
+#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
-union luai_Cast { double l_d; long l_l; };
-#define lua_number2int(i,d) \
- { volatile union luai_Cast u; u.l_d = (d) + 6755399441055744.0; (i) = u.l_l; }
-#define lua_number2integer(i,n) lua_number2int(i, n)
+#define MS_ASMTRICK
+#else /* }{ */
+/* the next definition uses a trick that should work on any machine
+ using IEEE754 with a 32-bit integer type */
+
+#define LUA_IEEE754TRICK
+
+/*
+@@ LUA_IEEEENDIAN is the endianness of doubles in your machine
+** (0 for little endian, 1 for big endian); if not defined, Lua will
+** check it dynamically.
+*/
+/* check for known architectures */
+#if defined(__i386__) || defined(__i386) || defined(__X86__) || \
+ defined (__x86_64)
+#define LUA_IEEEENDIAN 0
+#elif defined(__POWERPC__) || defined(__ppc__)
+#define LUA_IEEEENDIAN 1
#endif
+#endif /* } */
-/* this option always works, but may be slow */
-#else
-#define lua_number2int(i,d) ((i)=(int)(d))
-#define lua_number2integer(i,d) ((i)=(lua_Integer)(d))
+#endif /* } */
-#endif
+#endif /* } */
/* }================================================================== */
/*
-@@ LUAI_USER_ALIGNMENT_T is a type that requires maximum alignment.
-** CHANGE it if your system requires alignments larger than double. (For
-** instance, if your system supports long doubles and they must be
-** aligned in 16-byte boundaries, then you should add long double in the
-** union.) Probably you do not need to change this.
+@@ LUA_NANTRICK_LE/LUA_NANTRICK_BE controls the use of a trick to
+** pack all types into a single double value, using NaN values to
+** represent non-number values. The trick only works on 32-bit machines
+** (ints and pointers are 32-bit values) with numbers represented as
+** IEEE 754-2008 doubles with conventional endianess (12345678 or
+** 87654321), in CPUs that do not produce signaling NaN values (all NaNs
+** are quiet).
*/
-#define LUAI_USER_ALIGNMENT_T union { double u; void *s; long l; }
+#if defined(LUA_CORE) && \
+ defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
+/* little-endian architectures that satisfy those conditions */
+#if defined(__i386__) || defined(__i386) || defined(__X86__) || \
+ defined(_M_IX86)
-/*
-@@ LUAI_THROW/LUAI_TRY define how Lua does exception handling.
-** CHANGE them if you prefer to use longjmp/setjmp even with C++
-** or if want/don't to use _longjmp/_setjmp instead of regular
-** longjmp/setjmp. By default, Lua handles errors with exceptions when
-** compiling as C++ code, with _longjmp/_setjmp when asked to use them,
-** and with longjmp/setjmp otherwise.
-*/
-#if defined(__cplusplus)
-/* C++ exceptions */
-#define LUAI_THROW(L,c) throw(c)
-#define LUAI_TRY(L,c,a) try { a } catch(...) \
- { if ((c)->status == 0) (c)->status = -1; }
-#define luai_jmpbuf int /* dummy variable */
-
-#elif defined(LUA_USE_ULONGJMP)
-/* in Unix, try _longjmp/_setjmp (more efficient) */
-#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
-#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
-#define luai_jmpbuf jmp_buf
-
-#else
-/* default handling with long jumps */
-#define LUAI_THROW(L,c) longjmp((c)->b, 1)
-#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
-#define luai_jmpbuf jmp_buf
+#define LUA_NANTRICK_LE
#endif
+#endif /* } */
-/*
-@@ LUA_MAXCAPTURES is the maximum number of captures that a pattern
-@* can do during pattern-matching.
-** CHANGE it if you need more captures. This limit is arbitrary.
-*/
-#define LUA_MAXCAPTURES 32
-
-
-/*
-@@ lua_tmpnam is the function that the OS library uses to create a
-@* temporary name.
-@@ LUA_TMPNAMBUFSIZE is the maximum size of a name created by lua_tmpnam.
-** CHANGE them if you have an alternative to tmpnam (which is considered
-** insecure) or if you want the original tmpnam anyway. By default, Lua
-** uses tmpnam except when POSIX is available, where it uses mkstemp.
-*/
-#if defined(loslib_c) || defined(luaall_c)
-
-#if defined(LUA_USE_MKSTEMP)
-#include
-#define LUA_TMPNAMBUFSIZE 32
-#define lua_tmpnam(b,e) { \
- strcpy(b, "/tmp/lua_XXXXXX"); \
- e = mkstemp(b); \
- if (e != -1) close(e); \
- e = (e == -1); }
-
-#else
-#define LUA_TMPNAMBUFSIZE L_tmpnam
-#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
-#endif
-
-#endif
-
-
-/*
-@@ lua_popen spawns a new process connected to the current one through
-@* the file streams.
-** CHANGE it if you have a way to implement it in your system.
-*/
-#if defined(LUA_USE_POPEN)
-
-#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))
-#define lua_pclose(L,file) ((void)L, (pclose(file) != -1))
-
-#elif defined(LUA_WIN)
-
-#define lua_popen(L,c,m) ((void)L, _popen(c,m))
-#define lua_pclose(L,file) ((void)L, (_pclose(file) != -1))
-
-#else
-
-#define lua_popen(L,c,m) ((void)((void)c, m), \
- luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)
-#define lua_pclose(L,file) ((void)((void)L, file), 0)
-
-#endif
-
-/*
-@@ LUA_DL_* define which dynamic-library system Lua should use.
-** CHANGE here if Lua has problems choosing the appropriate
-** dynamic-library system for your platform (either Windows' DLL, Mac's
-** dyld, or Unix's dlopen). If your system is some kind of Unix, there
-** is a good chance that it has dlopen, so LUA_DL_DLOPEN will work for
-** it. To use dlopen you also need to adapt the src/Makefile (probably
-** adding -ldl to the linker options), so Lua does not select it
-** automatically. (When you change the makefile to add -ldl, you must
-** also add -DLUA_USE_DLOPEN.)
-** If you do not want any kind of dynamic library, undefine all these
-** options.
-** By default, _WIN32 gets LUA_DL_DLL and MAC OS X gets LUA_DL_DYLD.
-*/
-#if defined(LUA_USE_DLOPEN)
-#define LUA_DL_DLOPEN
-#endif
-
-#if defined(LUA_WIN)
-#define LUA_DL_DLL
-#endif
-
-
-/*
-@@ LUAI_EXTRASPACE allows you to add user-specific data in a lua_State
-@* (the data goes just *before* the lua_State pointer).
-** CHANGE (define) this if you really need that. This value must be
-** a multiple of the maximum alignment required for your machine.
-*/
-#define LUAI_EXTRASPACE 0
-
-
-/*
-@@ luai_userstate* allow user-specific actions on threads.
-** CHANGE them if you defined LUAI_EXTRASPACE and need to do something
-** extra when a thread is created/deleted/resumed/yielded.
-*/
-#define luai_userstateopen(L) ((void)L)
-#define luai_userstateclose(L) ((void)L)
-#define luai_userstatethread(L,L1) ((void)L)
-#define luai_userstatefree(L) ((void)L)
-#define luai_userstateresume(L,n) ((void)L)
-#define luai_userstateyield(L,n) ((void)L)
-
-
-/*
-@@ LUA_INTFRMLEN is the length modifier for integer conversions
-@* in 'string.format'.
-@@ LUA_INTFRM_T is the integer type correspoding to the previous length
-@* modifier.
-** CHANGE them if your system supports long long or does not support long.
-*/
-
-#if defined(LUA_USELONGLONG)
-
-#define LUA_INTFRMLEN "ll"
-#define LUA_INTFRM_T long long
-
-#else
-
-#define LUA_INTFRMLEN "l"
-#define LUA_INTFRM_T long
-
-#endif
diff --git a/l2detect/lua/lualib.h b/l2detect/lua/lualib.h
index 469417f..9fd126b 100644
--- a/l2detect/lua/lualib.h
+++ b/l2detect/lua/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.36.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -11,41 +11,43 @@
#include "lua.h"
-/* Key to file-handle type */
-#define LUA_FILEHANDLE "FILE*"
+LUAMOD_API int (luaopen_base) (lua_State *L);
#define LUA_COLIBNAME "coroutine"
-LUALIB_API int (luaopen_base) (lua_State *L);
+LUAMOD_API int (luaopen_coroutine) (lua_State *L);
#define LUA_TABLIBNAME "table"
-LUALIB_API int (luaopen_table) (lua_State *L);
+LUAMOD_API int (luaopen_table) (lua_State *L);
#define LUA_IOLIBNAME "io"
-LUALIB_API int (luaopen_io) (lua_State *L);
+LUAMOD_API int (luaopen_io) (lua_State *L);
#define LUA_OSLIBNAME "os"
-LUALIB_API int (luaopen_os) (lua_State *L);
+LUAMOD_API int (luaopen_os) (lua_State *L);
#define LUA_STRLIBNAME "string"
-LUALIB_API int (luaopen_string) (lua_State *L);
+LUAMOD_API int (luaopen_string) (lua_State *L);
+
+#define LUA_BITLIBNAME "bit32"
+LUAMOD_API int (luaopen_bit32) (lua_State *L);
#define LUA_MATHLIBNAME "math"
-LUALIB_API int (luaopen_math) (lua_State *L);
+LUAMOD_API int (luaopen_math) (lua_State *L);
#define LUA_DBLIBNAME "debug"
-LUALIB_API int (luaopen_debug) (lua_State *L);
+LUAMOD_API int (luaopen_debug) (lua_State *L);
#define LUA_LOADLIBNAME "package"
-LUALIB_API int (luaopen_package) (lua_State *L);
+LUAMOD_API int (luaopen_package) (lua_State *L);
/* open all previous libraries */
-LUALIB_API void (luaL_openlibs) (lua_State *L);
+LUALIB_API void (luaL_openlibs) (lua_State *L);
-#ifndef lua_assert
+#if !defined(lua_assert)
#define lua_assert(x) ((void)0)
#endif
diff --git a/l2detect/lua/lundump.c b/l2detect/lua/lundump.c
index 9c1504a..1a5085a 100644
--- a/l2detect/lua/lundump.c
+++ b/l2detect/lua/lundump.c
@@ -1,11 +1,10 @@
/*
-** $Id: lundump.c,v 2.7.1.4 2008/04/04 19:51:41 roberto Exp $
+** $Id: lundump.c,v 1.71 2011/12/07 10:39:12 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
-
-//#include
#include "stdafx.h"
+//#include
#define lundump_c
#define LUA_CORE
@@ -28,28 +27,24 @@ typedef struct {
const char* name;
} LoadState;
-#ifdef LUAC_TRUST_BINARIES
-#define IF(c,s)
-#define error(S,s)
-#else
-#define IF(c,s) if (c) error(S,s)
-
static void error(LoadState* S, const char* why)
{
- luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
+ luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);
luaD_throw(S->L,LUA_ERRSYNTAX);
}
-#endif
#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
-#define LoadByte(S) (lu_byte)LoadChar(S)
+#define LoadByte(S) (lu_byte)LoadChar(S)
#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
+#if !defined(luai_verifycode)
+#define luai_verifycode(L,b,f) (f)
+#endif
+
static void LoadBlock(LoadState* S, void* b, size_t size)
{
- size_t r=luaZ_read(S->Z,b,size);
- IF (r!=0, "unexpected end");
+ if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");
}
static int LoadChar(LoadState* S)
@@ -63,7 +58,7 @@ static int LoadInt(LoadState* S)
{
int x;
LoadVar(S,x);
- IF (x<0, "bad integer");
+ if (x<0) error(S,"corrupted");
return x;
}
@@ -83,7 +78,7 @@ static TString* LoadString(LoadState* S)
else
{
char* s=luaZ_openspace(S->L,S->b,size);
- LoadBlock(S,s,size);
+ LoadBlock(S,s,size*sizeof(char));
return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
}
}
@@ -96,7 +91,7 @@ static void LoadCode(LoadState* S, Proto* f)
LoadVector(S,f->code,n,sizeof(Instruction));
}
-static Proto* LoadFunction(LoadState* S, TString* p);
+static Proto* LoadFunction(LoadState* S);
static void LoadConstants(LoadState* S, Proto* f)
{
@@ -112,10 +107,10 @@ static void LoadConstants(LoadState* S, Proto* f)
switch (t)
{
case LUA_TNIL:
- setnilvalue(o);
+ setnilvalue(o);
break;
case LUA_TBOOLEAN:
- setbvalue(o,LoadChar(S)!=0);
+ setbvalue(o,LoadChar(S));
break;
case LUA_TNUMBER:
setnvalue(o,LoadNumber(S));
@@ -123,21 +118,33 @@ static void LoadConstants(LoadState* S, Proto* f)
case LUA_TSTRING:
setsvalue2n(S->L,o,LoadString(S));
break;
- default:
- error(S,"bad constant");
- break;
}
}
n=LoadInt(S);
f->p=luaM_newvector(S->L,n,Proto*);
f->sizep=n;
for (i=0; ip[i]=NULL;
- for (i=0; ip[i]=LoadFunction(S,f->source);
+ for (i=0; ip[i]=LoadFunction(S);
+}
+
+static void LoadUpvalues(LoadState* S, Proto* f)
+{
+ int i,n;
+ n=LoadInt(S);
+ f->upvalues=luaM_newvector(S->L,n,Upvaldesc);
+ f->sizeupvalues=n;
+ for (i=0; iupvalues[i].name=NULL;
+ for (i=0; iupvalues[i].instack=LoadByte(S);
+ f->upvalues[i].idx=LoadByte(S);
+ }
}
static void LoadDebug(LoadState* S, Proto* f)
{
int i,n;
+ f->source=LoadString(S);
n=LoadInt(S);
f->lineinfo=luaM_newvector(S->L,n,int);
f->sizelineinfo=n;
@@ -153,41 +160,43 @@ static void LoadDebug(LoadState* S, Proto* f)
f->locvars[i].endpc=LoadInt(S);
}
n=LoadInt(S);
- f->upvalues=luaM_newvector(S->L,n,TString*);
- f->sizeupvalues=n;
- for (i=0; iupvalues[i]=NULL;
- for (i=0; iupvalues[i]=LoadString(S);
+ for (i=0; iupvalues[i].name=LoadString(S);
}
-static Proto* LoadFunction(LoadState* S, TString* p)
+static Proto* LoadFunction(LoadState* S)
{
- Proto* f;
- if (++S->L->nCcalls > LUAI_MAXCCALLS) error(S,"code too deep");
- f=luaF_newproto(S->L);
+ Proto* f=luaF_newproto(S->L);
setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
- f->source=LoadString(S); if (f->source==NULL) f->source=p;
f->linedefined=LoadInt(S);
f->lastlinedefined=LoadInt(S);
- f->nups=LoadByte(S);
f->numparams=LoadByte(S);
f->is_vararg=LoadByte(S);
f->maxstacksize=LoadByte(S);
LoadCode(S,f);
LoadConstants(S,f);
+ LoadUpvalues(S,f);
LoadDebug(S,f);
- IF (!luaG_checkcode(f), "bad code");
S->L->top--;
- S->L->nCcalls--;
return f;
}
+/* the code below must be consistent with the code in luaU_header */
+#define N0 LUAC_HEADERSIZE
+#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char))
+#define N2 N1+2
+#define N3 N2+6
+
static void LoadHeader(LoadState* S)
{
- char h[LUAC_HEADERSIZE];
- char s[LUAC_HEADERSIZE];
+ lu_byte h[LUAC_HEADERSIZE];
+ lu_byte s[LUAC_HEADERSIZE];
luaU_header(h);
- LoadBlock(S,s,LUAC_HEADERSIZE);
- IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
+ memcpy(s,h,sizeof(char)); /* first char already read */
+ LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char));
+ if (memcmp(h,s,N0)==0) return;
+ if (memcmp(h,s,N1)!=0) error(S,"not a");
+ if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
+ if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
}
/*
@@ -206,23 +215,30 @@ Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
S.Z=Z;
S.b=buff;
LoadHeader(&S);
- return LoadFunction(&S,luaS_newliteral(L,"=?"));
+ return luai_verifycode(L,buff,LoadFunction(&S));
}
+#define MYINT(s) (s[0]-'0')
+#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
+#define FORMAT 0 /* this is the official format */
+
/*
-* make header
+* make header for precompiled chunks
+* if you change the code below be sure to update LoadHeader and FORMAT above
+* and LUAC_HEADERSIZE in lundump.h
*/
-void luaU_header (char* h)
+void luaU_header (lu_byte* h)
{
int x=1;
- memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
- h+=sizeof(LUA_SIGNATURE)-1;
- *h++=(char)LUAC_VERSION;
- *h++=(char)LUAC_FORMAT;
- *h++=(char)*(char*)&x; /* endianness */
- *h++=(char)sizeof(int);
- *h++=(char)sizeof(size_t);
- *h++=(char)sizeof(Instruction);
- *h++=(char)sizeof(lua_Number);
- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
+ memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char));
+ h+=sizeof(LUA_SIGNATURE)-sizeof(char);
+ *h++=cast_byte(VERSION);
+ *h++=cast_byte(FORMAT);
+ *h++=cast_byte(*(char*)&x); /* endianness */
+ *h++=cast_byte(sizeof(int));
+ *h++=cast_byte(sizeof(size_t));
+ *h++=cast_byte(sizeof(Instruction));
+ *h++=cast_byte(sizeof(lua_Number));
+ *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */
+ memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char));
}
diff --git a/l2detect/lua/lundump.h b/l2detect/lua/lundump.h
index c80189d..b63993f 100644
--- a/l2detect/lua/lundump.h
+++ b/l2detect/lua/lundump.h
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.h,v 1.37.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lundump.h,v 1.44 2011/05/06 13:35:17 lhf Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -14,23 +14,15 @@
LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
/* make header; from lundump.c */
-LUAI_FUNC void luaU_header (char* h);
+LUAI_FUNC void luaU_header (lu_byte* h);
/* dump one chunk; from ldump.c */
LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
-#ifdef luac_c
-/* print one chunk; from print.c */
-LUAI_FUNC void luaU_print (const Proto* f, int full);
-#endif
+/* data to catch conversion errors */
+#define LUAC_TAIL "\x19\x93\r\n\x1a\n"
-/* for header of binary files -- this is Lua 5.1 */
-#define LUAC_VERSION 0x51
-
-/* for header of binary files -- this is the official format */
-#define LUAC_FORMAT 0
-
-/* size of header of binary files */
-#define LUAC_HEADERSIZE 12
+/* size in bytes of header of binary files */
+#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char))
#endif
diff --git a/l2detect/lua/lvm.c b/l2detect/lua/lvm.c
index 6b137b9..971f564 100644
--- a/l2detect/lua/lvm.c
+++ b/l2detect/lua/lvm.c
@@ -1,14 +1,13 @@
/*
-** $Id: lvm.c,v 2.63.1.3 2007/12/28 15:32:23 roberto Exp $
+** $Id: lvm.c,v 2.147 2011/12/07 14:43:55 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
-
+#include "stdafx.h"
//#include
//#include
//#include
-#include "stdafx.h"
#define lvm_c
#define LUA_CORE
@@ -36,7 +35,7 @@
const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
lua_Number num;
if (ttisnumber(obj)) return obj;
- if (ttisstring(obj) && luaO_str2d(svalue(obj), &num)) {
+ if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
setnvalue(n, num);
return n;
}
@@ -51,58 +50,52 @@ int luaV_tostring (lua_State *L, StkId obj) {
else {
char s[LUAI_MAXNUMBER2STR];
lua_Number n = nvalue(obj);
- lua_number2str(s, n);
- setsvalue2s(L, obj, luaS_new(L, s));
+ int l = lua_number2str(s, n);
+ setsvalue2s(L, obj, luaS_newlstr(L, s, l));
return 1;
}
}
-static void traceexec (lua_State *L, const Instruction *pc) {
+static void traceexec (lua_State *L) {
+ CallInfo *ci = L->ci;
lu_byte mask = L->hookmask;
- const Instruction *oldpc = L->savedpc;
- L->savedpc = pc;
if ((mask & LUA_MASKCOUNT) && L->hookcount == 0) {
resethookcount(L);
- luaD_callhook(L, LUA_HOOKCOUNT, -1);
+ luaD_hook(L, LUA_HOOKCOUNT, -1);
}
if (mask & LUA_MASKLINE) {
- Proto *p = ci_func(L->ci)->l.p;
- int npc = pcRel(pc, p);
- int newline = getline(p, npc);
- /* call linehook when enter a new function, when jump back (loop),
- or when enter a new line */
- if (npc == 0 || pc <= oldpc || newline != getline(p, pcRel(oldpc, p)))
- luaD_callhook(L, LUA_HOOKLINE, newline);
+ Proto *p = ci_func(ci)->p;
+ int npc = pcRel(ci->u.l.savedpc, p);
+ int newline = getfuncline(p, npc);
+ if (npc == 0 || /* call linehook when enter a new function, */
+ ci->u.l.savedpc <= L->oldpc || /* when jump back (loop), or when */
+ newline != getfuncline(p, pcRel(L->oldpc, p))) /* enter a new line */
+ luaD_hook(L, LUA_HOOKLINE, newline);
+ }
+ L->oldpc = ci->u.l.savedpc;
+ if (L->status == LUA_YIELD) { /* did hook yield? */
+ ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
+ luaD_throw(L, LUA_YIELD);
}
}
-static void callTMres (lua_State *L, StkId res, const TValue *f,
- const TValue *p1, const TValue *p2) {
- ptrdiff_t result = savestack(L, res);
- setobj2s(L, L->top, f); /* push function */
- setobj2s(L, L->top+1, p1); /* 1st argument */
- setobj2s(L, L->top+2, p2); /* 2nd argument */
- luaD_checkstack(L, 3);
- L->top += 3;
- luaD_call(L, L->top - 3, 1);
- res = restorestack(L, result);
- L->top--;
- setobjs2s(L, res, L->top);
-}
-
-
-
static void callTM (lua_State *L, const TValue *f, const TValue *p1,
- const TValue *p2, const TValue *p3) {
- setobj2s(L, L->top, f); /* push function */
- setobj2s(L, L->top+1, p1); /* 1st argument */
- setobj2s(L, L->top+2, p2); /* 2nd argument */
- setobj2s(L, L->top+3, p3); /* 3th argument */
- luaD_checkstack(L, 4);
- L->top += 4;
- luaD_call(L, L->top - 4, 0);
+ const TValue *p2, TValue *p3, int hasres) {
+ ptrdiff_t result = savestack(L, p3);
+ setobj2s(L, L->top++, f); /* push function */
+ setobj2s(L, L->top++, p1); /* 1st argument */
+ setobj2s(L, L->top++, p2); /* 2nd argument */
+ if (!hasres) /* no result? 'p3' is third argument */
+ setobj2s(L, L->top++, p3); /* 3rd argument */
+ luaD_checkstack(L, 0);
+ /* metamethod may yield only when called from Lua code */
+ luaD_call(L, L->top - (4 - hasres), hasres, isLua(L->ci));
+ if (hasres) { /* if has result, move it to its place */
+ p3 = restorestack(L, result);
+ setobjs2s(L, p3, --L->top);
+ }
}
@@ -113,7 +106,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
const TValue *res = luaH_get(h, key); /* do a primitive get */
- if (!ttisnil(res) || /* result is no nil? */
+ if (!ttisnil(res) || /* result is not nil? */
(tm = fasttm(L, h->metatable, TM_INDEX)) == NULL) { /* or no TM? */
setobj2s(L, val, res);
return;
@@ -123,10 +116,10 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_INDEX)))
luaG_typeerror(L, t, "index");
if (ttisfunction(tm)) {
- callTMres(L, val, tm, t, key);
+ callTM(L, tm, t, key, val, 1);
return;
}
- t = tm; /* else repeat with `tm' */
+ t = tm; /* else repeat with 'tm' */
}
luaG_runerror(L, "loop in gettable");
}
@@ -138,22 +131,34 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */
Table *h = hvalue(t);
- TValue *oldval = luaH_set(L, h, key); /* do a primitive set */
- if (!ttisnil(oldval) || /* result is no nil? */
- (tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL) { /* or no TM? */
- setobj2t(L, oldval, val);
- luaC_barriert(L, h, val);
+ TValue *oldval = cast(TValue *, luaH_get(h, key));
+ /* if previous value is not nil, there must be a previous entry
+ in the table; moreover, a metamethod has no relevance */
+ if (!ttisnil(oldval) ||
+ /* previous value is nil; must check the metamethod */
+ ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
+ /* no metamethod; is there a previous entry in the table? */
+ (oldval != luaO_nilobject ||
+ /* no previous entry; must create one. (The next test is
+ always true; we only need the assignment.) */
+ (oldval = luaH_newkey(L, h, key), 1)))) {
+ /* no metamethod and (now) there is an entry with given key */
+ setobj2t(L, oldval, val); /* assign new value to that entry */
+ invalidateTMcache(h);
+ luaC_barrierback(L, obj2gco(h), val);
return;
}
- /* else will try the tag method */
+ /* else will try the metamethod */
}
- else if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
- luaG_typeerror(L, t, "index");
+ else /* not a table; check metamethod */
+ if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
+ luaG_typeerror(L, t, "index");
+ /* there is a metamethod */
if (ttisfunction(tm)) {
- callTM(L, tm, t, key, val);
+ callTM(L, tm, t, key, val, 0);
return;
}
- t = tm; /* else repeat with `tm' */
+ t = tm; /* else repeat with 'tm' */
}
luaG_runerror(L, "loop in settable");
}
@@ -165,12 +170,12 @@ static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
if (ttisnil(tm))
tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
if (ttisnil(tm)) return 0;
- callTMres(L, res, tm, p1, p2);
+ callTM(L, tm, p1, p2, res, 1);
return 1;
}
-static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
+static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
TMS event) {
const TValue *tm1 = fasttm(L, mt1, event);
const TValue *tm2;
@@ -178,7 +183,7 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
tm2 = fasttm(L, mt2, event);
if (tm2 == NULL) return NULL; /* no metamethod */
- if (luaO_rawequalObj(tm1, tm2)) /* same metamethods? */
+ if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */
return tm1;
return NULL;
}
@@ -186,14 +191,10 @@ static const TValue *get_compTM (lua_State *L, Table *mt1, Table *mt2,
static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
TMS event) {
- const TValue *tm1 = luaT_gettmbyobj(L, p1, event);
- const TValue *tm2;
- if (ttisnil(tm1)) return -1; /* no metamethod? */
- tm2 = luaT_gettmbyobj(L, p2, event);
- if (!luaO_rawequalObj(tm1, tm2)) /* different metamethods? */
- return -1;
- callTMres(L, L->top, tm1, p1, p2);
- return !l_isfalse(L->top);
+ if (!call_binTM(L, p1, p2, L->top, event))
+ return -1; /* no metamethod */
+ else
+ return !l_isfalse(L->top);
}
@@ -221,125 +222,259 @@ static int l_strcmp (const TString *ls, const TString *rs) {
int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int res;
- if (ttype(l) != ttype(r))
- return luaG_ordererror(L, l, r);
- else if (ttisnumber(l))
- return luai_numlt(nvalue(l), nvalue(r));
- else if (ttisstring(l))
+ if (ttisnumber(l) && ttisnumber(r))
+ return luai_numlt(L, nvalue(l), nvalue(r));
+ else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
- else if ((res = call_orderTM(L, l, r, TM_LT)) != -1)
- return res;
- return luaG_ordererror(L, l, r);
+ else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
+ luaG_ordererror(L, l, r);
+ return res;
}
-static int lessequal (lua_State *L, const TValue *l, const TValue *r) {
+int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
- if (ttype(l) != ttype(r))
- return luaG_ordererror(L, l, r);
- else if (ttisnumber(l))
- return luai_numle(nvalue(l), nvalue(r));
- else if (ttisstring(l))
+ if (ttisnumber(l) && ttisnumber(r))
+ return luai_numle(L, nvalue(l), nvalue(r));
+ else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
- else if ((res = call_orderTM(L, l, r, TM_LE)) != -1) /* first try `le' */
+ else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
return res;
- else if ((res = call_orderTM(L, r, l, TM_LT)) != -1) /* else try `lt' */
- return !res;
- return luaG_ordererror(L, l, r);
+ else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
+ luaG_ordererror(L, l, r);
+ return !res;
}
-int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2) {
+/*
+** equality of Lua values. L == NULL means raw equality (no metamethods)
+*/
+int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
const TValue *tm;
- lua_assert(ttype(t1) == ttype(t2));
+ lua_assert(ttisequal(t1, t2));
switch (ttype(t1)) {
case LUA_TNIL: return 1;
case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
case LUA_TBOOLEAN: return bvalue(t1) == bvalue(t2); /* true must be 1 !! */
case LUA_TLIGHTUSERDATA: return pvalue(t1) == pvalue(t2);
+ case LUA_TLCF: return fvalue(t1) == fvalue(t2);
+ case LUA_TSTRING: return eqstr(rawtsvalue(t1), rawtsvalue(t2));
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
- tm = get_compTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable,
- TM_EQ);
+ else if (L == NULL) return 0;
+ tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
break; /* will try TM */
}
case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1;
- tm = get_compTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
+ else if (L == NULL) return 0;
+ tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
break; /* will try TM */
}
- default: return gcvalue(t1) == gcvalue(t2);
+ default:
+ lua_assert(iscollectable(t1));
+ return gcvalue(t1) == gcvalue(t2);
}
if (tm == NULL) return 0; /* no TM? */
- callTMres(L, L->top, tm, t1, t2); /* call TM */
+ callTM(L, tm, t1, t2, L->top, 1); /* call TM */
return !l_isfalse(L->top);
}
-void luaV_concat (lua_State *L, int total, int last) {
+void luaV_concat (lua_State *L, int total) {
+ lua_assert(total >= 2);
do {
- StkId top = L->base + last + 1;
+ StkId top = L->top;
int n = 2; /* number of elements handled in this pass (at least 2) */
if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1)) {
if (!call_binTM(L, top-2, top-1, top-2, TM_CONCAT))
luaG_concaterror(L, top-2, top-1);
- } else if (tsvalue(top-1)->len == 0) /* second op is empty? */
- (void)tostring(L, top - 2); /* result is first op (as string) */
+ }
+ else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
+ (void)tostring(L, top - 2); /* result is first operand */
+ else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
+ setsvalue2s(L, top-2, rawtsvalue(top-1)); /* result is second op. */
+ }
else {
- /* at least two string values; get as many as possible */
+ /* at least two non-empty string values; get as many as possible */
size_t tl = tsvalue(top-1)->len;
char *buffer;
int i;
/* collect total length */
- for (n = 1; n < total && tostring(L, top-n-1); n++) {
- size_t l = tsvalue(top-n-1)->len;
- if (l >= MAX_SIZET - tl) luaG_runerror(L, "string length overflow");
+ for (i = 1; i < total && tostring(L, top-i-1); i++) {
+ size_t l = tsvalue(top-i-1)->len;
+ if (l >= (MAX_SIZET/sizeof(char)) - tl)
+ luaG_runerror(L, "string length overflow");
tl += l;
}
buffer = luaZ_openspace(L, &G(L)->buff, tl);
tl = 0;
- for (i=n; i>0; i--) { /* concat all strings */
+ n = i;
+ do { /* concat all strings */
size_t l = tsvalue(top-i)->len;
- memcpy(buffer+tl, svalue(top-i), l);
+ memcpy(buffer+tl, svalue(top-i), l * sizeof(char));
tl += l;
- }
+ } while (--i > 0);
setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
}
- total -= n-1; /* got `n' strings to create 1 new */
- last -= n-1;
+ total -= n-1; /* got 'n' strings to create 1 new */
+ L->top -= n-1; /* popped 'n' strings and pushed one */
} while (total > 1); /* repeat until only 1 result left */
}
-static void Arith (lua_State *L, StkId ra, const TValue *rb,
- const TValue *rc, TMS op) {
+void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
+ const TValue *tm;
+ switch (ttypenv(rb)) {
+ case LUA_TTABLE: {
+ Table *h = hvalue(rb);
+ tm = fasttm(L, h->metatable, TM_LEN);
+ if (tm) break; /* metamethod? break switch to call it */
+ setnvalue(ra, cast_num(luaH_getn(h))); /* else primitive len */
+ return;
+ }
+ case LUA_TSTRING: {
+ setnvalue(ra, cast_num(tsvalue(rb)->len));
+ return;
+ }
+ default: { /* try metamethod */
+ tm = luaT_gettmbyobj(L, rb, TM_LEN);
+ if (ttisnil(tm)) /* no metamethod? */
+ luaG_typeerror(L, rb, "get length of");
+ break;
+ }
+ }
+ callTM(L, tm, rb, rb, ra, 1);
+}
+
+
+void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
+ const TValue *rc, TMS op) {
TValue tempb, tempc;
const TValue *b, *c;
if ((b = luaV_tonumber(rb, &tempb)) != NULL &&
(c = luaV_tonumber(rc, &tempc)) != NULL) {
- lua_Number nb = nvalue(b), nc = nvalue(c);
- switch (op) {
- case TM_ADD: setnvalue(ra, luai_numadd(nb, nc)); break;
- case TM_SUB: setnvalue(ra, luai_numsub(nb, nc)); break;
- case TM_MUL: setnvalue(ra, luai_nummul(nb, nc)); break;
- case TM_DIV: setnvalue(ra, luai_numdiv(nb, nc)); break;
- case TM_MOD: setnvalue(ra, luai_nummod(nb, nc)); break;
- case TM_POW: setnvalue(ra, luai_numpow(nb, nc)); break;
- case TM_UNM: setnvalue(ra, luai_numunm(nb)); break;
- default: lua_assert(0); break;
- }
+ lua_Number res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
+ setnvalue(ra, res);
}
else if (!call_binTM(L, rb, rc, ra, op))
luaG_aritherror(L, rb, rc);
}
+/*
+** check whether cached closure in prototype 'p' may be reused, that is,
+** whether there is a cached closure with the same upvalues needed by
+** new closure to be created.
+*/
+static Closure *getcached (Proto *p, UpVal **encup, StkId base) {
+ Closure *c = p->cache;
+ if (c != NULL) { /* is there a cached closure? */
+ int nup = p->sizeupvalues;
+ Upvaldesc *uv = p->upvalues;
+ int i;
+ for (i = 0; i < nup; i++) { /* check whether it has right upvalues */
+ TValue *v = uv[i].instack ? base + uv[i].idx : encup[uv[i].idx]->v;
+ if (c->l.upvals[i]->v != v)
+ return NULL; /* wrong upvalue; cannot reuse closure */
+ }
+ }
+ return c; /* return cached closure (or NULL if no cached closure) */
+}
+
+
+/*
+** create a new Lua closure, push it in the stack, and initialize
+** its upvalues. Note that the call to 'luaC_barrierproto' must come
+** before the assignment to 'p->cache', as the function needs the
+** original value of that field.
+*/
+static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
+ StkId ra) {
+ int nup = p->sizeupvalues;
+ Upvaldesc *uv = p->upvalues;
+ int i;
+ Closure *ncl = luaF_newLclosure(L, p);
+ setclLvalue(L, ra, ncl); /* anchor new closure in stack */
+ for (i = 0; i < nup; i++) { /* fill in its upvalues */
+ if (uv[i].instack) /* upvalue refers to local variable? */
+ ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
+ else /* get upvalue from enclosing function */
+ ncl->l.upvals[i] = encup[uv[i].idx];
+ }
+ luaC_barrierproto(L, p, ncl);
+ p->cache = ncl; /* save it on cache for reuse */
+}
+
+
+/*
+** finish execution of an opcode interrupted by an yield
+*/
+void luaV_finishOp (lua_State *L) {
+ CallInfo *ci = L->ci;
+ StkId base = ci->u.l.base;
+ Instruction inst = *(ci->u.l.savedpc - 1); /* interrupted instruction */
+ OpCode op = GET_OPCODE(inst);
+ switch (op) { /* finish its execution */
+ case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV:
+ case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:
+ case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
+ setobjs2s(L, base + GETARG_A(inst), --L->top);
+ break;
+ }
+ case OP_LE: case OP_LT: case OP_EQ: {
+ int res = !l_isfalse(L->top - 1);
+ L->top--;
+ /* metamethod should not be called when operand is K */
+ lua_assert(!ISK(GETARG_B(inst)));
+ if (op == OP_LE && /* "<=" using "<" instead? */
+ ttisnil(luaT_gettmbyobj(L, base + GETARG_B(inst), TM_LE)))
+ res = !res; /* invert result */
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_JMP);
+ if (res != GETARG_A(inst)) /* condition failed? */
+ ci->u.l.savedpc++; /* skip jump instruction */
+ break;
+ }
+ case OP_CONCAT: {
+ StkId top = L->top - 1; /* top when 'call_binTM' was called */
+ int b = GETARG_B(inst); /* first element to concatenate */
+ int total = cast_int(top - 1 - (base + b)); /* yet to concatenate */
+ setobj2s(L, top - 2, top); /* put TM result in proper position */
+ if (total > 1) { /* are there elements to concat? */
+ L->top = top - 1; /* top is one after last element (at top-2) */
+ luaV_concat(L, total); /* concat them (may yield again) */
+ }
+ /* move final result to final position */
+ setobj2s(L, ci->u.l.base + GETARG_A(inst), L->top - 1);
+ L->top = ci->top; /* restore top */
+ break;
+ }
+ case OP_TFORCALL: {
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_TFORLOOP);
+ L->top = ci->top; /* correct top */
+ break;
+ }
+ case OP_CALL: {
+ if (GETARG_C(inst) - 1 >= 0) /* nresults >= 0? */
+ L->top = ci->top; /* adjust results */
+ break;
+ }
+ case OP_TAILCALL: case OP_SETTABUP: case OP_SETTABLE:
+ break;
+ default: lua_assert(0);
+ }
+}
+
+
/*
** some macros for common tasks in `luaV_execute'
*/
-#define runtime_check(L, c) { if (!(c)) break; }
+#if !defined luai_runtimecheck
+#define luai_runtimecheck(L, c) /* void */
+#endif
+
#define RA(i) (base+GETARG_A(i))
/* to be used after possible stack reallocation */
@@ -349,13 +484,23 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
ISK(GETARG_B(i)) ? k+INDEXK(GETARG_B(i)) : base+GETARG_B(i))
#define RKC(i) check_exp(getCMode(GET_OPCODE(i)) == OpArgK, \
ISK(GETARG_C(i)) ? k+INDEXK(GETARG_C(i)) : base+GETARG_C(i))
-#define KBx(i) check_exp(getBMode(GET_OPCODE(i)) == OpArgK, k+GETARG_Bx(i))
+#define KBx(i) \
+ (k + (GETARG_Bx(i) != 0 ? GETARG_Bx(i) - 1 : GETARG_Ax(*ci->u.l.savedpc++)))
-#define dojump(L,pc,i) {(pc) += (i); luai_threadyield(L);}
+/* execute a jump instruction */
+#define dojump(ci,i,e) \
+ { int a = GETARG_A(i); \
+ if (a > 0) luaF_close(L, ci->u.l.base + a - 1); \
+ ci->u.l.savedpc += GETARG_sBx(i) + e; }
+
+/* for test instructions, execute the jump instruction that follows it */
+#define donextjump(ci) { i = *ci->u.l.savedpc; dojump(ci, i, 1); }
-#define Protect(x) { L->savedpc = pc; {x;}; base = L->base; }
+#define Protect(x) { {x;}; base = ci->u.l.base; }
+
+#define checkGC(L,c) Protect(luaC_condGC(L, c); luai_threadyield(L);)
#define arith_op(op,tm) { \
@@ -363,401 +508,356 @@ static void Arith (lua_State *L, StkId ra, const TValue *rb,
TValue *rc = RKC(i); \
if (ttisnumber(rb) && ttisnumber(rc)) { \
lua_Number nb = nvalue(rb), nc = nvalue(rc); \
- setnvalue(ra, op(nb, nc)); \
+ setnvalue(ra, op(L, nb, nc)); \
} \
- else \
- Protect(Arith(L, ra, rb, rc, tm)); \
- }
+ else { Protect(luaV_arith(L, ra, rb, rc, tm)); } }
+#define vmdispatch(o) switch(o)
+#define vmcase(l,b) case l: {b} break;
+#define vmcasenb(l,b) case l: {b} /* nb = no break */
-void luaV_execute (lua_State *L, int nexeccalls) {
+void luaV_execute (lua_State *L) {
+ CallInfo *ci = L->ci;
LClosure *cl;
- StkId base;
TValue *k;
- const Instruction *pc;
- reentry: /* entry point */
- lua_assert(isLua(L->ci));
- pc = L->savedpc;
- cl = &clvalue(L->ci->func)->l;
- base = L->base;
+ StkId base;
+ newframe: /* reentry point when frame changes (call/return) */
+ lua_assert(ci == L->ci);
+ cl = clLvalue(ci->func);
k = cl->p->k;
+ base = ci->u.l.base;
/* main loop of interpreter */
for (;;) {
- const Instruction i = *pc++;
+ Instruction i = *(ci->u.l.savedpc++);
StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
- traceexec(L, pc);
- if (L->status == LUA_YIELD) { /* did hook yield? */
- L->savedpc = pc - 1;
- return;
- }
- base = L->base;
+ Protect(traceexec(L));
}
- /* warning!! several calls may realloc the stack and invalidate `ra' */
+ /* WARNING: several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
- lua_assert(base == L->base && L->base == L->ci->base);
- lua_assert(base <= L->top && L->top <= L->stack + L->stacksize);
- lua_assert(L->top == L->ci->top || luaG_checkopenop(i));
- switch (GET_OPCODE(i)) {
- case OP_MOVE: {
+ lua_assert(base == ci->u.l.base);
+ lua_assert(base <= L->top && L->top < L->stack + L->stacksize);
+ vmdispatch (GET_OPCODE(i)) {
+ vmcase(OP_MOVE,
setobjs2s(L, ra, RB(i));
- continue;
- }
- case OP_LOADK: {
- setobj2s(L, ra, KBx(i));
- continue;
- }
- case OP_LOADBOOL: {
+ )
+ vmcase(OP_LOADK,
+ TValue *rb = k + GETARG_Bx(i);
+ setobj2s(L, ra, rb);
+ )
+ vmcase(OP_LOADKX,
+ TValue *rb;
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+ rb = k + GETARG_Ax(*ci->u.l.savedpc++);
+ setobj2s(L, ra, rb);
+ )
+ vmcase(OP_LOADBOOL,
setbvalue(ra, GETARG_B(i));
- if (GETARG_C(i)) pc++; /* skip next instruction (if C) */
- continue;
- }
- case OP_LOADNIL: {
- TValue *rb = RB(i);
+ if (GETARG_C(i)) ci->u.l.savedpc++; /* skip next instruction (if C) */
+ )
+ vmcase(OP_LOADNIL,
+ int b = GETARG_B(i);
do {
- setnilvalue(rb--);
- } while (rb >= ra);
- continue;
- }
- case OP_GETUPVAL: {
+ setnilvalue(ra++);
+ } while (b--);
+ )
+ vmcase(OP_GETUPVAL,
int b = GETARG_B(i);
setobj2s(L, ra, cl->upvals[b]->v);
- continue;
- }
- case OP_GETGLOBAL: {
- TValue g;
- TValue *rb = KBx(i);
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(rb));
- Protect(luaV_gettable(L, &g, rb, ra));
- continue;
- }
- case OP_GETTABLE: {
+ )
+ vmcase(OP_GETTABUP,
+ int b = GETARG_B(i);
+ Protect(luaV_gettable(L, cl->upvals[b]->v, RKC(i), ra));
+ )
+ vmcase(OP_GETTABLE,
Protect(luaV_gettable(L, RB(i), RKC(i), ra));
- continue;
- }
- case OP_SETGLOBAL: {
- TValue g;
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(KBx(i)));
- Protect(luaV_settable(L, &g, KBx(i), ra));
- continue;
- }
- case OP_SETUPVAL: {
+ )
+ vmcase(OP_SETTABUP,
+ int a = GETARG_A(i);
+ Protect(luaV_settable(L, cl->upvals[a]->v, RKB(i), RKC(i)));
+ )
+ vmcase(OP_SETUPVAL,
UpVal *uv = cl->upvals[GETARG_B(i)];
setobj(L, uv->v, ra);
luaC_barrier(L, uv, ra);
- continue;
- }
- case OP_SETTABLE: {
+ )
+ vmcase(OP_SETTABLE,
Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
- continue;
- }
- case OP_NEWTABLE: {
+ )
+ vmcase(OP_NEWTABLE,
int b = GETARG_B(i);
int c = GETARG_C(i);
- sethvalue(L, ra, luaH_new(L, luaO_fb2int(b), luaO_fb2int(c)));
- Protect(luaC_checkGC(L));
- continue;
- }
- case OP_SELF: {
+ Table *t = luaH_new(L);
+ sethvalue(L, ra, t);
+ if (b != 0 || c != 0)
+ luaH_resize(L, t, luaO_fb2int(b), luaO_fb2int(c));
+ checkGC(L,
+ L->top = ra + 1; /* limit of live values */
+ luaC_step(L);
+ L->top = ci->top; /* restore top */
+ )
+ )
+ vmcase(OP_SELF,
StkId rb = RB(i);
setobjs2s(L, ra+1, rb);
Protect(luaV_gettable(L, rb, RKC(i), ra));
- continue;
- }
- case OP_ADD: {
+ )
+ vmcase(OP_ADD,
arith_op(luai_numadd, TM_ADD);
- continue;
- }
- case OP_SUB: {
+ )
+ vmcase(OP_SUB,
arith_op(luai_numsub, TM_SUB);
- continue;
- }
- case OP_MUL: {
+ )
+ vmcase(OP_MUL,
arith_op(luai_nummul, TM_MUL);
- continue;
- }
- case OP_DIV: {
+ )
+ vmcase(OP_DIV,
arith_op(luai_numdiv, TM_DIV);
- continue;
- }
- case OP_MOD: {
+ )
+ vmcase(OP_MOD,
arith_op(luai_nummod, TM_MOD);
- continue;
- }
- case OP_POW: {
+ )
+ vmcase(OP_POW,
arith_op(luai_numpow, TM_POW);
- continue;
- }
- case OP_UNM: {
+ )
+ vmcase(OP_UNM,
TValue *rb = RB(i);
if (ttisnumber(rb)) {
lua_Number nb = nvalue(rb);
- setnvalue(ra, luai_numunm(nb));
+ setnvalue(ra, luai_numunm(L, nb));
}
else {
- Protect(Arith(L, ra, rb, rb, TM_UNM));
+ Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
}
- continue;
- }
- case OP_NOT: {
- int res = l_isfalse(RB(i)); /* next assignment may change this value */
+ )
+ vmcase(OP_NOT,
+ TValue *rb = RB(i);
+ int res = l_isfalse(rb); /* next assignment may change this value */
setbvalue(ra, res);
- continue;
- }
- case OP_LEN: {
- const TValue *rb = RB(i);
- switch (ttype(rb)) {
- case LUA_TTABLE: {
- setnvalue(ra, cast_num(luaH_getn(hvalue(rb))));
- break;
- }
- case LUA_TSTRING: {
- setnvalue(ra, cast_num(tsvalue(rb)->len));
- break;
- }
- default: { /* try metamethod */
- Protect(
- if (!call_binTM(L, rb, luaO_nilobject, ra, TM_LEN))
- luaG_typeerror(L, rb, "get length of");
- )
- }
- }
- continue;
- }
- case OP_CONCAT: {
+ )
+ vmcase(OP_LEN,
+ Protect(luaV_objlen(L, ra, RB(i)));
+ )
+ vmcase(OP_CONCAT,
int b = GETARG_B(i);
int c = GETARG_C(i);
- Protect(luaV_concat(L, c-b+1, c); luaC_checkGC(L));
- setobjs2s(L, RA(i), base+b);
- continue;
- }
- case OP_JMP: {
- dojump(L, pc, GETARG_sBx(i));
- continue;
- }
- case OP_EQ: {
+ StkId rb;
+ L->top = base + c + 1; /* mark the end of concat operands */
+ Protect(luaV_concat(L, c - b + 1));
+ ra = RA(i); /* 'luav_concat' may invoke TMs and move the stack */
+ rb = b + base;
+ setobjs2s(L, ra, rb);
+ checkGC(L,
+ L->top = (ra >= rb ? ra + 1 : rb); /* limit of live values */
+ luaC_step(L);
+ )
+ L->top = ci->top; /* restore top */
+ )
+ vmcase(OP_JMP,
+ dojump(ci, i, 0);
+ )
+ vmcase(OP_EQ,
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
- if (equalobj(L, rb, rc) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
+ if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
+ ci->u.l.savedpc++;
+ else
+ donextjump(ci);
)
- pc++;
- continue;
- }
- case OP_LT: {
+ )
+ vmcase(OP_LT,
Protect(
- if (luaV_lessthan(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
+ if (luaV_lessthan(L, RKB(i), RKC(i)) != GETARG_A(i))
+ ci->u.l.savedpc++;
+ else
+ donextjump(ci);
)
- pc++;
- continue;
- }
- case OP_LE: {
+ )
+ vmcase(OP_LE,
Protect(
- if (lessequal(L, RKB(i), RKC(i)) == GETARG_A(i))
- dojump(L, pc, GETARG_sBx(*pc));
+ if (luaV_lessequal(L, RKB(i), RKC(i)) != GETARG_A(i))
+ ci->u.l.savedpc++;
+ else
+ donextjump(ci);
)
- pc++;
- continue;
- }
- case OP_TEST: {
- if (l_isfalse(ra) != GETARG_C(i))
- dojump(L, pc, GETARG_sBx(*pc));
- pc++;
- continue;
- }
- case OP_TESTSET: {
+ )
+ vmcase(OP_TEST,
+ if (GETARG_C(i) ? l_isfalse(ra) : !l_isfalse(ra))
+ ci->u.l.savedpc++;
+ else
+ donextjump(ci);
+ )
+ vmcase(OP_TESTSET,
TValue *rb = RB(i);
- if (l_isfalse(rb) != GETARG_C(i)) {
+ if (GETARG_C(i) ? l_isfalse(rb) : !l_isfalse(rb))
+ ci->u.l.savedpc++;
+ else {
setobjs2s(L, ra, rb);
- dojump(L, pc, GETARG_sBx(*pc));
+ donextjump(ci);
}
- pc++;
- continue;
- }
- case OP_CALL: {
+ )
+ vmcase(OP_CALL,
int b = GETARG_B(i);
int nresults = GETARG_C(i) - 1;
if (b != 0) L->top = ra+b; /* else previous instruction set top */
- L->savedpc = pc;
- switch (luaD_precall(L, ra, nresults)) {
- case PCRLUA: {
- nexeccalls++;
- goto reentry; /* restart luaV_execute over new Lua function */
- }
- case PCRC: {
- /* it was a C function (`precall' called it); adjust results */
- if (nresults >= 0) L->top = L->ci->top;
- base = L->base;
- continue;
- }
- default: {
- return; /* yield */
- }
+ if (luaD_precall(L, ra, nresults)) { /* C function? */
+ if (nresults >= 0) L->top = ci->top; /* adjust results */
+ base = ci->u.l.base;
}
- }
- case OP_TAILCALL: {
+ else { /* Lua function */
+ ci = L->ci;
+ ci->callstatus |= CIST_REENTRY;
+ goto newframe; /* restart luaV_execute over new Lua function */
+ }
+ )
+ vmcase(OP_TAILCALL,
int b = GETARG_B(i);
if (b != 0) L->top = ra+b; /* else previous instruction set top */
- L->savedpc = pc;
lua_assert(GETARG_C(i) - 1 == LUA_MULTRET);
- switch (luaD_precall(L, ra, LUA_MULTRET)) {
- case PCRLUA: {
- /* tail call: put new frame in place of previous one */
- CallInfo *ci = L->ci - 1; /* previous frame */
- int aux;
- StkId func = ci->func;
- StkId pfunc = (ci+1)->func; /* previous function index */
- if (L->openupval) luaF_close(L, ci->base);
- L->base = ci->base = ci->func + ((ci+1)->base - pfunc);
- for (aux = 0; pfunc+aux < L->top; aux++) /* move frame down */
- setobjs2s(L, func+aux, pfunc+aux);
- ci->top = L->top = func+aux; /* correct top */
- lua_assert(L->top == L->base + clvalue(func)->l.p->maxstacksize);
- ci->savedpc = L->savedpc;
- ci->tailcalls++; /* one more call lost */
- L->ci--; /* remove new frame */
- goto reentry;
- }
- case PCRC: { /* it was a C function (`precall' called it) */
- base = L->base;
- continue;
- }
- default: {
- return; /* yield */
- }
+ if (luaD_precall(L, ra, LUA_MULTRET)) /* C function? */
+ base = ci->u.l.base;
+ else {
+ /* tail call: put called frame (n) in place of caller one (o) */
+ CallInfo *nci = L->ci; /* called frame */
+ CallInfo *oci = nci->previous; /* caller frame */
+ StkId nfunc = nci->func; /* called function */
+ StkId ofunc = oci->func; /* caller function */
+ /* last stack slot filled by 'precall' */
+ StkId lim = nci->u.l.base + getproto(nfunc)->numparams;
+ int aux;
+ /* close all upvalues from previous call */
+ if (cl->p->sizep > 0) luaF_close(L, oci->u.l.base);
+ /* move new frame into old one */
+ for (aux = 0; nfunc + aux < lim; aux++)
+ setobjs2s(L, ofunc + aux, nfunc + aux);
+ oci->u.l.base = ofunc + (nci->u.l.base - nfunc); /* correct base */
+ oci->top = L->top = ofunc + (L->top - nfunc); /* correct top */
+ oci->u.l.savedpc = nci->u.l.savedpc;
+ oci->callstatus |= CIST_TAIL; /* function was tail called */
+ ci = L->ci = oci; /* remove new frame */
+ lua_assert(L->top == oci->u.l.base + getproto(ofunc)->maxstacksize);
+ goto newframe; /* restart luaV_execute over new Lua function */
}
- }
- case OP_RETURN: {
+ )
+ vmcasenb(OP_RETURN,
int b = GETARG_B(i);
if (b != 0) L->top = ra+b-1;
- if (L->openupval) luaF_close(L, base);
- L->savedpc = pc;
+ if (cl->p->sizep > 0) luaF_close(L, base);
b = luaD_poscall(L, ra);
- if (--nexeccalls == 0) /* was previous function running `here'? */
- return; /* no: return */
- else { /* yes: continue its execution */
- if (b) L->top = L->ci->top;
- lua_assert(isLua(L->ci));
- lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
- goto reentry;
+ if (!(ci->callstatus & CIST_REENTRY)) /* 'ci' still the called one */
+ return; /* external invocation: return */
+ else { /* invocation via reentry: continue execution */
+ ci = L->ci;
+ if (b) L->top = ci->top;
+ lua_assert(isLua(ci));
+ lua_assert(GET_OPCODE(*((ci)->u.l.savedpc - 1)) == OP_CALL);
+ goto newframe; /* restart luaV_execute over new Lua function */
}
- }
- case OP_FORLOOP: {
+ )
+ vmcase(OP_FORLOOP,
lua_Number step = nvalue(ra+2);
- lua_Number idx = luai_numadd(nvalue(ra), step); /* increment index */
+ lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
lua_Number limit = nvalue(ra+1);
- if (luai_numlt(0, step) ? luai_numle(idx, limit)
- : luai_numle(limit, idx)) {
- dojump(L, pc, GETARG_sBx(i)); /* jump back */
+ if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)
+ : luai_numle(L, limit, idx)) {
+ ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
setnvalue(ra, idx); /* update internal index... */
setnvalue(ra+3, idx); /* ...and external index */
}
- continue;
- }
- case OP_FORPREP: {
+ )
+ vmcase(OP_FORPREP,
const TValue *init = ra;
const TValue *plimit = ra+1;
const TValue *pstep = ra+2;
- L->savedpc = pc; /* next steps may throw errors */
if (!tonumber(init, ra))
luaG_runerror(L, LUA_QL("for") " initial value must be a number");
else if (!tonumber(plimit, ra+1))
luaG_runerror(L, LUA_QL("for") " limit must be a number");
else if (!tonumber(pstep, ra+2))
luaG_runerror(L, LUA_QL("for") " step must be a number");
- setnvalue(ra, luai_numsub(nvalue(ra), nvalue(pstep)));
- dojump(L, pc, GETARG_sBx(i));
- continue;
- }
- case OP_TFORLOOP: {
+ setnvalue(ra, luai_numsub(L, nvalue(ra), nvalue(pstep)));
+ ci->u.l.savedpc += GETARG_sBx(i);
+ )
+ vmcasenb(OP_TFORCALL,
StkId cb = ra + 3; /* call base */
setobjs2s(L, cb+2, ra+2);
setobjs2s(L, cb+1, ra+1);
setobjs2s(L, cb, ra);
- L->top = cb+3; /* func. + 2 args (state and index) */
- Protect(luaD_call(L, cb, GETARG_C(i)));
- L->top = L->ci->top;
- cb = RA(i) + 3; /* previous call may change the stack */
- if (!ttisnil(cb)) { /* continue loop? */
- setobjs2s(L, cb-1, cb); /* save control variable */
- dojump(L, pc, GETARG_sBx(*pc)); /* jump back */
+ L->top = cb + 3; /* func. + 2 args (state and index) */
+ Protect(luaD_call(L, cb, GETARG_C(i), 1));
+ L->top = ci->top;
+ i = *(ci->u.l.savedpc++); /* go to next instruction */
+ ra = RA(i);
+ lua_assert(GET_OPCODE(i) == OP_TFORLOOP);
+ goto l_tforloop;
+ )
+ vmcase(OP_TFORLOOP,
+ l_tforloop:
+ if (!ttisnil(ra + 1)) { /* continue loop? */
+ setobjs2s(L, ra, ra + 1); /* save control variable */
+ ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
}
- pc++;
- continue;
- }
- case OP_SETLIST: {
+ )
+ vmcase(OP_SETLIST,
int n = GETARG_B(i);
int c = GETARG_C(i);
int last;
Table *h;
- if (n == 0) {
- n = cast_int(L->top - ra) - 1;
- L->top = L->ci->top;
+ if (n == 0) n = cast_int(L->top - ra) - 1;
+ if (c == 0) {
+ lua_assert(GET_OPCODE(*ci->u.l.savedpc) == OP_EXTRAARG);
+ c = GETARG_Ax(*ci->u.l.savedpc++);
}
- if (c == 0) c = cast_int(*pc++);
- runtime_check(L, ttistable(ra));
+ luai_runtimecheck(L, ttistable(ra));
h = hvalue(ra);
last = ((c-1)*LFIELDS_PER_FLUSH) + n;
if (last > h->sizearray) /* needs more space? */
- luaH_resizearray(L, h, last); /* pre-alloc it at once */
+ luaH_resizearray(L, h, last); /* pre-allocate it at once */
for (; n > 0; n--) {
TValue *val = ra+n;
- setobj2t(L, luaH_setnum(L, h, last--), val);
- luaC_barriert(L, h, val);
+ luaH_setint(L, h, last--, val);
+ luaC_barrierback(L, obj2gco(h), val);
}
- continue;
- }
- case OP_CLOSE: {
- luaF_close(L, ra);
- continue;
- }
- case OP_CLOSURE: {
- Proto *p;
- Closure *ncl;
- int nup, j;
- p = cl->p->p[GETARG_Bx(i)];
- nup = p->nups;
- ncl = luaF_newLclosure(L, nup, cl->env);
- ncl->l.p = p;
- for (j=0; jl.upvals[j] = cl->upvals[GETARG_B(*pc)];
- else {
- lua_assert(GET_OPCODE(*pc) == OP_MOVE);
- ncl->l.upvals[j] = luaF_findupval(L, base + GETARG_B(*pc));
- }
- }
- setclvalue(L, ra, ncl);
- Protect(luaC_checkGC(L));
- continue;
- }
- case OP_VARARG: {
+ L->top = ci->top; /* correct top (in case of previous open call) */
+ )
+ vmcase(OP_CLOSURE,
+ Proto *p = cl->p->p[GETARG_Bx(i)];
+ Closure *ncl = getcached(p, cl->upvals, base); /* cached closure */
+ if (ncl == NULL) /* no match? */
+ pushclosure(L, p, cl->upvals, base, ra); /* create a new one */
+ else
+ setclLvalue(L, ra, ncl); /* push cashed closure */
+ checkGC(L,
+ L->top = ra + 1; /* limit of live values */
+ luaC_step(L);
+ L->top = ci->top; /* restore top */
+ )
+ )
+ vmcase(OP_VARARG,
int b = GETARG_B(i) - 1;
int j;
- CallInfo *ci = L->ci;
- int n = cast_int(ci->base - ci->func) - cl->p->numparams - 1;
- if (b == LUA_MULTRET) {
+ int n = cast_int(base - ci->func) - cl->p->numparams - 1;
+ if (b < 0) { /* B == 0? */
+ b = n; /* get all var. arguments */
Protect(luaD_checkstack(L, n));
ra = RA(i); /* previous call may change the stack */
- b = n;
L->top = ra + n;
}
for (j = 0; j < b; j++) {
if (j < n) {
- setobjs2s(L, ra + j, ci->base - n + j);
+ setobjs2s(L, ra + j, base - n + j);
}
else {
setnilvalue(ra + j);
}
}
- continue;
- }
+ )
+ vmcase(OP_EXTRAARG,
+ lua_assert(0);
+ )
}
}
}
diff --git a/l2detect/lua/lvm.h b/l2detect/lua/lvm.h
index bfe4f56..ec35822 100644
--- a/l2detect/lua/lvm.h
+++ b/l2detect/lua/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.5.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lvm.h,v 2.17 2011/05/31 18:27:56 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -13,24 +13,33 @@
#include "ltm.h"
-#define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
+#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
-#define tonumber(o,n) (ttype(o) == LUA_TNUMBER || \
- (((o) = luaV_tonumber(o,n)) != NULL))
+#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
-#define equalobj(L,o1,o2) \
- (ttype(o1) == ttype(o2) && luaV_equalval(L, o1, o2))
+#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2))
+
+#define luaV_rawequalobj(t1,t2) \
+ (ttisequal(t1,t2) && luaV_equalobj_(NULL,t1,t2))
+
+
+/* not to called directly */
+LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2);
LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
-LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
+LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
LUAI_FUNC const TValue *luaV_tonumber (const TValue *obj, TValue *n);
LUAI_FUNC int luaV_tostring (lua_State *L, StkId obj);
LUAI_FUNC void luaV_gettable (lua_State *L, const TValue *t, TValue *key,
StkId val);
LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
StkId val);
-LUAI_FUNC void luaV_execute (lua_State *L, int nexeccalls);
-LUAI_FUNC void luaV_concat (lua_State *L, int total, int last);
+LUAI_FUNC void luaV_finishOp (lua_State *L);
+LUAI_FUNC void luaV_execute (lua_State *L);
+LUAI_FUNC void luaV_concat (lua_State *L, int total);
+LUAI_FUNC void luaV_arith (lua_State *L, StkId ra, const TValue *rb,
+ const TValue *rc, TMS op);
+LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
#endif
diff --git a/l2detect/lua/lzio.c b/l2detect/lua/lzio.c
index 84da391..0082f9c 100644
--- a/l2detect/lua/lzio.c
+++ b/l2detect/lua/lzio.c
@@ -1,12 +1,11 @@
/*
-** $Id: lzio.c,v 1.31.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lzio.c,v 1.34 2011/07/15 12:35:32 roberto Exp $
** a generic input stream interface
** See Copyright Notice in lua.h
*/
-
-//#include
#include "stdafx.h"
+//#include
#define lzio_c
#define LUA_CORE
@@ -26,23 +25,11 @@ int luaZ_fill (ZIO *z) {
lua_unlock(L);
buff = z->reader(L, z->data, &size);
lua_lock(L);
- if (buff == NULL || size == 0) return EOZ;
- z->n = size - 1;
+ if (buff == NULL || size == 0)
+ return EOZ;
+ z->n = size - 1; /* discount char being returned */
z->p = buff;
- return char2int(*(z->p++));
-}
-
-
-int luaZ_lookahead (ZIO *z) {
- if (z->n == 0) {
- if (luaZ_fill(z) == EOZ)
- return EOZ;
- else {
- z->n++; /* luaZ_fill removed first byte; put back it */
- z->p--;
- }
- }
- return char2int(*z->p);
+ return cast_uchar(*(z->p++));
}
@@ -59,8 +46,14 @@ void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader, void *data) {
size_t luaZ_read (ZIO *z, void *b, size_t n) {
while (n) {
size_t m;
- if (luaZ_lookahead(z) == EOZ)
- return n; /* return number of missing bytes */
+ if (z->n == 0) { /* no bytes in buffer? */
+ if (luaZ_fill(z) == EOZ) /* try to read more */
+ return n; /* no more input; return number of missing bytes */
+ else {
+ z->n++; /* luaZ_fill consumed first byte; put it back */
+ z->p--;
+ }
+ }
m = (n <= z->n) ? n : z->n; /* min. between n and z->n */
memcpy(b, z->p, m);
z->n -= m;
diff --git a/l2detect/lua/lzio.h b/l2detect/lua/lzio.h
index 51d695d..0868230 100644
--- a/l2detect/lua/lzio.h
+++ b/l2detect/lua/lzio.h
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.h,v 1.21.1.1 2007/12/27 13:02:25 roberto Exp $
+** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/
@@ -17,9 +17,8 @@
typedef struct Zio ZIO;
-#define char2int(c) cast(int, cast(unsigned char, (c)))
+#define zgetc(z) (((z)->n--)>0 ? cast_uchar(*(z)->p++) : luaZ_fill(z))
-#define zgetc(z) (((z)->n--)>0 ? char2int(*(z)->p++) : luaZ_fill(z))
typedef struct Mbuffer {
char *buffer;
@@ -47,7 +46,6 @@ LUAI_FUNC char *luaZ_openspace (lua_State *L, Mbuffer *buff, size_t n);
LUAI_FUNC void luaZ_init (lua_State *L, ZIO *z, lua_Reader reader,
void *data);
LUAI_FUNC size_t luaZ_read (ZIO* z, void* b, size_t n); /* read next n bytes */
-LUAI_FUNC int luaZ_lookahead (ZIO *z);
@@ -56,7 +54,7 @@ LUAI_FUNC int luaZ_lookahead (ZIO *z);
struct Zio {
size_t n; /* bytes still unread */
const char *p; /* current position in buffer */
- lua_Reader reader;
+ lua_Reader reader; /* reader function */
void* data; /* additional data */
lua_State *L; /* Lua state (for reader) */
};