summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLua Team <team@lua.org>2013-07-06 12:00:00 +0000
committerrepogen <>2013-07-06 12:00:00 +0000
commit87cc247b6b22184fba47184c218a642ea7a49e96 (patch)
tree299ba8b72b95aa32336b5c810b7133f8efc4fb29 /src
parentdc27609467d2699ac9252e89d632432ac5f798f2 (diff)
downloadlua-github-5.3.0-work1.tar.gz
Lua 5.3.0-work15.3.0-work1
Diffstat (limited to 'src')
-rw-r--r--src/.fix2
-rw-r--r--src/Makefile9
-rw-r--r--src/lapi.c141
-rw-r--r--src/lauxlib.c47
-rw-r--r--src/lauxlib.h14
-rw-r--r--src/lbaselib.c71
-rw-r--r--src/lbitlib.c18
-rw-r--r--src/lcode.c126
-rw-r--r--src/lcode.h6
-rw-r--r--src/ldblib.c15
-rw-r--r--src/ldebug.c70
-rw-r--r--src/ldebug.h9
-rw-r--r--src/ldo.c15
-rw-r--r--src/ldump.c20
-rw-r--r--src/lgc.c13
-rw-r--r--src/liolib.c45
-rw-r--r--src/llex.c57
-rw-r--r--src/llex.h8
-rw-r--r--src/llimits.h113
-rw-r--r--src/lmathlib.c56
-rw-r--r--src/lobject.c161
-rw-r--r--src/lobject.h143
-rw-r--r--src/lopcodes.c4
-rw-r--r--src/lopcodes.h3
-rw-r--r--src/loslib.c10
-rw-r--r--src/lparser.c19
-rw-r--r--src/lparser.h8
-rw-r--r--src/lstring.c6
-rw-r--r--src/lstrlib.c109
-rw-r--r--src/ltable.c83
-rw-r--r--src/ltable.h7
-rw-r--r--src/ltm.c74
-rw-r--r--src/ltm.h17
-rw-r--r--src/lua.h24
-rw-r--r--src/luac.c6
-rw-r--r--src/luaconf.h200
-rw-r--r--src/lundump.c16
-rw-r--r--src/lvm.c418
-rw-r--r--src/lvm.h25
-rw-r--r--src/lzio.h6
40 files changed, 1275 insertions, 919 deletions
diff --git a/src/.fix b/src/.fix
new file mode 100644
index 00000000..b390c3ca
--- /dev/null
+++ b/src/.fix
@@ -0,0 +1,2 @@
+#define nvalue(x) 0
+#define ttypenv(x) ttnov(x)
diff --git a/src/Makefile b/src/Makefile
index fea895bc..ca156758 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -7,7 +7,7 @@
PLAT= none
CC= gcc
-CFLAGS= -O2 -Wall -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
+CFLAGS= -O2 -Wall -Wextra -DLUA_COMPAT_ALL $(SYSCFLAGS) $(MYCFLAGS)
LDFLAGS= $(SYSLDFLAGS) $(MYLDFLAGS)
LIBS= -lm $(SYSLIBS) $(MYLIBS)
@@ -106,7 +106,7 @@ linux:
$(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_LINUX" SYSLIBS="-Wl,-E -ldl -lreadline"
macosx:
- $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline"
+ $(MAKE) $(ALL) SYSCFLAGS="-DLUA_USE_MACOSX" SYSLIBS="-lreadline" CC=cc
mingw:
$(MAKE) "LUA_A=lua52.dll" "LUA_T=lua.exe" \
@@ -173,8 +173,8 @@ lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
ltablib.o: ltablib.c lua.h luaconf.h lauxlib.h lualib.h
-ltm.o: ltm.c lua.h luaconf.h lobject.h llimits.h lstate.h ltm.h lzio.h \
- lmem.h lstring.h lgc.h ltable.h
+ltm.o: ltm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
+ lzio.h lmem.h ldo.h lstring.h lgc.h ltable.h lvm.h
lua.o: lua.c lua.h luaconf.h lauxlib.h lualib.h
luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \
ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
@@ -185,3 +185,4 @@ lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
lzio.h
+# (end of Makefile)
diff --git a/src/lapi.c b/src/lapi.c
index 791d8545..a8c3e1c8 100644
--- a/src/lapi.c
+++ b/src/lapi.c
@@ -1,10 +1,11 @@
/*
-** $Id: lapi.c,v 2.171 2013/03/16 21:10:18 roberto Exp $
+** $Id: lapi.c,v 2.185 2013/07/05 14:29:51 roberto Exp $
** Lua API
** See Copyright Notice in lua.h
*/
+#include <math.h>
#include <stdarg.h>
#include <string.h>
@@ -248,7 +249,7 @@ LUA_API void lua_pushvalue (lua_State *L, int idx) {
LUA_API int lua_type (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
- return (isvalid(o) ? ttypenv(o) : LUA_TNONE);
+ return (isvalid(o) ? ttnov(o) : LUA_TNONE);
}
@@ -264,8 +265,14 @@ LUA_API int lua_iscfunction (lua_State *L, int idx) {
}
+LUA_API int lua_isinteger (lua_State *L, int idx) {
+ StkId o = index2addr(L, idx);
+ return ttisinteger(o);
+}
+
+
LUA_API int lua_isnumber (lua_State *L, int idx) {
- TValue n;
+ lua_Number n;
const TValue *o = index2addr(L, idx);
return tonumber(o, &n);
}
@@ -291,8 +298,6 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) {
LUA_API void lua_arith (lua_State *L, int op) {
- StkId o1; /* 1st operand */
- StkId o2; /* 2nd operand */
lua_lock(L);
if (op != LUA_OPUNM) /* all other operations expect two operands */
api_checknelems(L, 2);
@@ -301,14 +306,9 @@ LUA_API void lua_arith (lua_State *L, int op) {
setobjs2s(L, L->top, L->top - 1);
L->top++;
}
- o1 = L->top - 2;
- o2 = L->top - 1;
- if (ttisnumber(o1) && ttisnumber(o2)) {
- setnvalue(o1, luaO_arith(op, nvalue(o1), nvalue(o2)));
- }
- else
- luaV_arith(L, o1, o1, o2, cast(TMS, op - LUA_OPADD + TM_ADD));
- L->top--;
+ /* first operand at top - 2, second at top - 1; result go to top - 2 */
+ luaO_arith(L, op, L->top - 2, L->top - 1, L->top - 2);
+ L->top--; /* remove second operand */
lua_unlock(L);
}
@@ -321,7 +321,7 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
o2 = index2addr(L, index2);
if (isvalid(o1) && isvalid(o2)) {
switch (op) {
- case LUA_OPEQ: i = equalobj(L, o1, o2); break;
+ case LUA_OPEQ: i = luaV_equalobj(L, o1, o2); break;
case LUA_OPLT: i = luaV_lessthan(L, o1, o2); break;
case LUA_OPLE: i = luaV_lessequal(L, o1, o2); break;
default: api_check(L, 0, "invalid option");
@@ -332,51 +332,74 @@ LUA_API int lua_compare (lua_State *L, int index1, int index2, int op) {
}
-LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *isnum) {
- TValue n;
- const TValue *o = index2addr(L, idx);
- if (tonumber(o, &n)) {
- if (isnum) *isnum = 1;
- return nvalue(o);
+LUA_API int lua_strtonum (lua_State *L, const char *s, size_t len) {
+ lua_Integer i; lua_Number n;
+ if (luaO_str2int(s, len, &i)) { /* try as an integer */
+ setivalue(L->top, i);
}
- else {
- if (isnum) *isnum = 0;
- return 0;
+ else if (luaO_str2d(s, len, &n)) { /* else try as a float */
+ setnvalue(L->top, n);
}
+ else
+ return 0; /* conversion failed */
+ api_incr_top(L);
+ return 1;
}
-LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *isnum) {
- TValue n;
+LUA_API lua_Number lua_tonumberx (lua_State *L, int idx, int *pisnum) {
+ lua_Number n;
const TValue *o = index2addr(L, idx);
- if (tonumber(o, &n)) {
- lua_Integer res;
- lua_Number num = nvalue(o);
- lua_number2integer(res, num);
- if (isnum) *isnum = 1;
- return res;
- }
- else {
- if (isnum) *isnum = 0;
- return 0;
- }
+ int isnum = tonumber(o, &n);
+ if (!isnum)
+ n = 0; /* call to 'tonumber' may change 'n' even if it fails */
+ if (pisnum) *pisnum = isnum;
+ return n;
}
-LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *isnum) {
- TValue n;
+LUA_API lua_Integer lua_tointegerx (lua_State *L, int idx, int *pisnum) {
+ lua_Integer res;
const TValue *o = index2addr(L, idx);
- if (tonumber(o, &n)) {
- lua_Unsigned res;
- lua_Number num = nvalue(o);
- lua_number2unsigned(res, num);
- if (isnum) *isnum = 1;
- return res;
- }
- else {
- if (isnum) *isnum = 0;
- return 0;
+ int isnum = tointeger(o, &res);
+ if (!isnum)
+ res = 0; /* call to 'tointeger' may change 'n' even if it fails */
+ if (pisnum) *pisnum = isnum;
+ return res;
+}
+
+
+LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *pisnum) {
+ lua_Unsigned res = 0;
+ const TValue *o = index2addr(L, idx);
+ int isnum = 0;
+ switch (ttype(o)) {
+ case LUA_TNUMINT: {
+ res = cast_unsigned(ivalue(o));
+ isnum = 1;
+ break;
+ }
+ case LUA_TNUMFLT: {
+ const lua_Number twop = (~(lua_Unsigned)0) + cast_num(1);
+ lua_Number n = fltvalue(o);
+ int neg = 0;
+ n = l_floor(n);
+ if (n < 0) {
+ neg = 1;
+ n = -n;
+ }
+ n = l_mathop(fmod)(n, twop);
+ if (luai_numisnan(L,n)) /* not a number? */
+ break; /* not an integer, too */
+ res = cast_unsigned(n);
+ if (neg) res = 0u - res;
+ isnum = 1;
+ break;
+ }
+ default: break;
}
+ if (pisnum) *pisnum = isnum;
+ return res;
}
@@ -406,7 +429,7 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
LUA_API size_t lua_rawlen (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
- switch (ttypenv(o)) {
+ switch (ttnov(o)) {
case LUA_TSTRING: return tsvalue(o)->len;
case LUA_TUSERDATA: return uvalue(o)->len;
case LUA_TTABLE: return luaH_getn(hvalue(o));
@@ -426,7 +449,7 @@ LUA_API lua_CFunction lua_tocfunction (lua_State *L, int idx) {
LUA_API void *lua_touserdata (lua_State *L, int idx) {
StkId o = index2addr(L, idx);
- switch (ttypenv(o)) {
+ switch (ttnov(o)) {
case LUA_TUSERDATA: return (rawuvalue(o) + 1);
case LUA_TLIGHTUSERDATA: return pvalue(o);
default: return NULL;
@@ -482,17 +505,15 @@ LUA_API void lua_pushnumber (lua_State *L, lua_Number n) {
LUA_API void lua_pushinteger (lua_State *L, lua_Integer n) {
lua_lock(L);
- setnvalue(L->top, cast_num(n));
+ setivalue(L->top, n);
api_incr_top(L);
lua_unlock(L);
}
LUA_API void lua_pushunsigned (lua_State *L, lua_Unsigned u) {
- lua_Number n;
lua_lock(L);
- n = lua_unsigned2number(u);
- setnvalue(L->top, n);
+ setivalue(L->top, cast_integer(u));
api_incr_top(L);
lua_unlock(L);
}
@@ -646,7 +667,7 @@ 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_rawgeti (lua_State *L, int idx, lua_Integer n) {
StkId t;
lua_lock(L);
t = index2addr(L, idx);
@@ -689,7 +710,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
int res;
lua_lock(L);
obj = index2addr(L, objindex);
- switch (ttypenv(obj)) {
+ switch (ttnov(obj)) {
case LUA_TTABLE:
mt = hvalue(obj)->metatable;
break;
@@ -697,7 +718,7 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) {
mt = uvalue(obj)->metatable;
break;
default:
- mt = G(L)->mt[ttypenv(obj)];
+ mt = G(L)->mt[ttnov(obj)];
break;
}
if (mt == NULL)
@@ -781,7 +802,7 @@ 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_rawseti (lua_State *L, int idx, lua_Integer n) {
StkId t;
lua_lock(L);
api_checknelems(L, 1);
@@ -821,7 +842,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
api_check(L, ttistable(L->top - 1), "table expected");
mt = hvalue(L->top - 1);
}
- switch (ttypenv(obj)) {
+ switch (ttnov(obj)) {
case LUA_TTABLE: {
hvalue(obj)->metatable = mt;
if (mt) {
@@ -839,7 +860,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) {
break;
}
default: {
- G(L)->mt[ttypenv(obj)] = mt;
+ G(L)->mt[ttnov(obj)] = mt;
break;
}
}
diff --git a/src/lauxlib.c b/src/lauxlib.c
index 2e989d66..68373b0a 100644
--- a/src/lauxlib.c
+++ b/src/lauxlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.c,v 1.248 2013/03/21 13:54:57 roberto Exp $
+** $Id: lauxlib.c,v 1.255 2013/06/27 18:32:33 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -386,11 +386,20 @@ LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {
}
+static void interror (lua_State *L, int narg) {
+ if (lua_type(L, narg) == LUA_TNUMBER)
+ luaL_argerror(L, narg, "float value out of range");
+ else
+ tag_error(L, narg, LUA_TNUMBER);
+}
+
+
LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {
int isnum;
lua_Integer d = lua_tointegerx(L, narg, &isnum);
- if (!isnum)
- tag_error(L, narg, LUA_TNUMBER);
+ if (!isnum) {
+ interror(L, narg);
+ }
return d;
}
@@ -399,7 +408,7 @@ LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {
int isnum;
lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);
if (!isnum)
- tag_error(L, narg, LUA_TNUMBER);
+ interror(L, narg);
return d;
}
@@ -722,13 +731,13 @@ LUALIB_API int luaL_callmeta (lua_State *L, int obj, const char *event) {
}
-LUALIB_API int luaL_len (lua_State *L, int idx) {
- int l;
+LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
+ lua_Integer l;
int isnum;
lua_len(L, idx);
- l = (int)lua_tointegerx(L, -1, &isnum);
+ l = lua_tointegerx(L, -1, &isnum);
if (!isnum)
- luaL_error(L, "object length is not a number");
+ luaL_error(L, "object length is not an integer");
lua_pop(L, 1); /* remove object */
return l;
}
@@ -737,7 +746,12 @@ LUALIB_API int luaL_len (lua_State *L, int idx) {
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
switch (lua_type(L, idx)) {
- case LUA_TNUMBER:
+ case LUA_TNUMBER: { /* concatenate with empty string to convert */
+ lua_pushvalue(L, idx);
+ lua_pushliteral(L, "");
+ lua_concat(L, 2);
+ break;
+ }
case LUA_TSTRING:
lua_pushvalue(L, idx);
break;
@@ -846,7 +860,6 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
** Returns with only the table at the stack.
*/
LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) {
- luaL_checkversion(L);
luaL_checkstack(L, nup, "too many upvalues");
for (; l->name != NULL; l++) { /* fill the table with given functions */
int i;
@@ -941,19 +954,15 @@ LUALIB_API lua_State *luaL_newstate (void) {
}
-LUALIB_API void luaL_checkversion_ (lua_State *L, lua_Number ver) {
+LUALIB_API void luaL_checkversion_ (lua_State *L, int ver, size_t sz) {
const lua_Number *v = lua_version(L);
if (v != lua_version(NULL))
luaL_error(L, "multiple Lua VMs detected");
else if (*v != ver)
- luaL_error(L, "version mismatch: app. needs %f, Lua core provides %f",
+ luaL_error(L, "version mismatch: app. needs %d, Lua core provides %f",
ver, *v);
- /* check conversions number -> integer types */
- lua_pushnumber(L, -(lua_Number)0x1234);
- if (lua_tointeger(L, -1) != -0x1234 ||
- lua_tounsigned(L, -1) != (lua_Unsigned)-0x1234)
- luaL_error(L, "bad conversion number->int;"
- " must recompile Lua with proper settings");
- lua_pop(L, 1);
+ /* check numeric types */
+ if (sz != LUAL_NUMSIZES)
+ luaL_error(L, "core and library have incompatible numeric types");
}
diff --git a/src/lauxlib.h b/src/lauxlib.h
index ac4d15fb..6b345e28 100644
--- a/src/lauxlib.h
+++ b/src/lauxlib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lauxlib.h,v 1.120 2011/11/29 15:55:08 roberto Exp $
+** $Id: lauxlib.h,v 1.122 2013/06/27 18:32:33 roberto Exp $
** Auxiliary functions for building Lua libraries
** See Copyright Notice in lua.h
*/
@@ -26,8 +26,11 @@ typedef struct luaL_Reg {
} luaL_Reg;
-LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver);
-#define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM)
+#define LUAL_NUMSIZES (sizeof(lua_Integer)*16 + sizeof(lua_Number))
+
+LUALIB_API void (luaL_checkversion_) (lua_State *L, int ver, size_t sz);
+#define luaL_checkversion(L) \
+ luaL_checkversion_(L, LUA_VERSION_NUM, LUAL_NUMSIZES)
LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
@@ -83,7 +86,7 @@ LUALIB_API int (luaL_loadstring) (lua_State *L, const char *s);
LUALIB_API lua_State *(luaL_newstate) (void);
-LUALIB_API int (luaL_len) (lua_State *L, int idx);
+LUALIB_API lua_Integer (luaL_len) (lua_State *L, int idx);
LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p,
const char *r);
@@ -108,7 +111,8 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname,
#define luaL_newlibtable(L,l) \
lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1)
-#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
+#define luaL_newlib(L,l) \
+ (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
#define luaL_argcheck(L, cond,numarg,extramsg) \
((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))
diff --git a/src/lbaselib.c b/src/lbaselib.c
index 540e9a5c..d074b92d 100644
--- a/src/lbaselib.c
+++ b/src/lbaselib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbaselib.c,v 1.276 2013/02/21 13:44:53 roberto Exp $
+** $Id: lbaselib.c,v 1.279 2013/07/05 14:39:15 roberto Exp $
** Basic library
** See Copyright Notice in lua.h
*/
@@ -45,42 +45,57 @@ static int luaB_print (lua_State *L) {
#define SPACECHARS " \f\n\r\t\v"
+static int b_str2int (const char *s, const char *e, int base, lua_Integer *pn) {
+ lua_Unsigned n = 0;
+ int neg = 0;
+ s += strspn(s, SPACECHARS); /* skip initial spaces */
+ if (*s == '-') { s++; neg = 1; } /* handle signal */
+ else if (*s == '+') s++;
+ if (!isalnum((unsigned char)*s)) /* no digit? */
+ return 0;
+ do {
+ int digit = (isdigit((unsigned char)*s)) ? *s - '0'
+ : toupper((unsigned char)*s) - 'A' + 10;
+ if (digit >= base) return 0; /* invalid numeral */
+ n = n * base + digit;
+ s++;
+ } while (isalnum((unsigned char)*s));
+ s += strspn(s, SPACECHARS); /* skip trailing spaces */
+ if (s != e) /* invalid trailing characters? */
+ return 0;
+ *pn = (neg) ? -(lua_Integer)n : (lua_Integer)n;
+ return 1;
+}
+
+
static int luaB_tonumber (lua_State *L) {
if (lua_isnoneornil(L, 2)) { /* standard conversion */
- int isnum;
- lua_Number n = lua_tonumberx(L, 1, &isnum);
- if (isnum) {
- lua_pushnumber(L, n);
- return 1;
- } /* else not a number; must be something */
luaL_checkany(L, 1);
+ if (lua_type(L, 1) == LUA_TNUMBER) { /* already a number? */
+ lua_settop(L, 1); /* yes; return it */
+ return 1;
+ }
+ else {
+ size_t l;
+ const char *s = lua_tolstring(L, 1, &l);
+ if (s != NULL && lua_strtonum(L, s, l)) /* can convert to a number? */
+ return 1;
+ /* else not a number */
+ }
}
else {
size_t l;
- const char *s = luaL_checklstring(L, 1, &l);
- const char *e = s + l; /* end point for 's' */
+ const char *s;
+ lua_Integer n;
int base = luaL_checkint(L, 2);
- int neg = 0;
+ luaL_checktype(L, 1, LUA_TSTRING); /* before 'luaL_checklstring'! */
+ s = luaL_checklstring(L, 1, &l);
luaL_argcheck(L, 2 <= base && base <= 36, 2, "base out of range");
- s += strspn(s, SPACECHARS); /* skip initial spaces */
- if (*s == '-') { s++; neg = 1; } /* handle signal */
- else if (*s == '+') s++;
- if (isalnum((unsigned char)*s)) {
- lua_Number n = 0;
- do {
- int digit = (isdigit((unsigned char)*s)) ? *s - '0'
- : toupper((unsigned char)*s) - 'A' + 10;
- if (digit >= base) break; /* invalid numeral; force a fail */
- n = n * (lua_Number)base + (lua_Number)digit;
- s++;
- } while (isalnum((unsigned char)*s));
- s += strspn(s, SPACECHARS); /* skip trailing spaces */
- if (s == e) { /* no invalid trailing characters? */
- lua_pushnumber(L, (neg) ? -n : n);
- return 1;
- } /* else not a number */
+ if (b_str2int(s, s + l, base, &n)) {
+ lua_pushinteger(L, n);
+ return 1;
} /* else not a number */
- }
+ } /* else not a number */
lua_pushnil(L); /* not a number */
return 1;
}
diff --git a/src/lbitlib.c b/src/lbitlib.c
index 9637532e..d6d436bc 100644
--- a/src/lbitlib.c
+++ b/src/lbitlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lbitlib.c,v 1.18 2013/03/19 13:19:12 roberto Exp $
+** $Id: lbitlib.c,v 1.20 2013/06/21 17:27:24 roberto Exp $
** Standard library for bitwise operations
** See Copyright Notice in lua.h
*/
@@ -19,7 +19,12 @@
#endif
-#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
+/* type with (at least) LUA_NBITS bits */
+typedef unsigned long b_uint;
+
+
+#define ALLONES (~(((~(b_uint)0) << (LUA_NBITS - 1)) << 1))
+
/* macro to trim extra bits */
#define trim(x) ((x) & ALLONES)
@@ -29,9 +34,6 @@
#define mask(n) (~((ALLONES << 1) << ((n) - 1)))
-typedef lua_Unsigned b_uint;
-
-
static b_uint andaux (lua_State *L) {
int i, n = lua_gettop(L);
@@ -118,7 +120,7 @@ static int b_arshift (lua_State *L) {
else { /* arithmetic shift for 'negative' number */
if (i >= LUA_NBITS) r = ALLONES;
else
- r = trim((r >> i) | ~(~(b_uint)0 >> i)); /* add signal bit */
+ r = trim((r >> i) | ~(trim(~(b_uint)0) >> i)); /* add signal bit */
lua_pushunsigned(L, r);
return 1;
}
@@ -165,7 +167,7 @@ static int fieldargs (lua_State *L, int farg, int *width) {
static int b_extract (lua_State *L) {
int w;
- b_uint r = luaL_checkunsigned(L, 1);
+ b_uint r = trim(luaL_checkunsigned(L, 1));
int f = fieldargs(L, 2, &w);
r = (r >> f) & mask(w);
lua_pushunsigned(L, r);
@@ -175,7 +177,7 @@ static int b_extract (lua_State *L) {
static int b_replace (lua_State *L) {
int w;
- b_uint r = luaL_checkunsigned(L, 1);
+ b_uint r = trim(luaL_checkunsigned(L, 1));
b_uint v = luaL_checkunsigned(L, 2);
int f = fieldargs(L, 3, &w);
int m = mask(w);
diff --git a/src/lcode.c b/src/lcode.c
index 56c26ac8..261090e0 100644
--- a/src/lcode.c
+++ b/src/lcode.c
@@ -1,10 +1,11 @@
/*
-** $Id: lcode.c,v 2.62 2012/08/16 17:34:28 roberto Exp $
+** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
+#include <math.h>
#include <stdlib.h>
#define lcode_c
@@ -26,11 +27,29 @@
#include "lvm.h"
+/* test for x == -0 */
+#if defined(signbit)
+#define isminuszero(x) ((x) == 0.0 && signbit(x))
+#else
+#define isminuszero(x) ((x) == 0.0 && 1.0/(x) < 0.0)
+#endif
+
+
#define hasjumps(e) ((e)->t != (e)->f)
-static int isnumeral(expdesc *e) {
- return (e->k == VKNUM && e->t == NO_JUMP && e->f == NO_JUMP);
+static int tonumeral(expdesc *e, TValue *v) {
+ if (e->t != NO_JUMP || e->f != NO_JUMP)
+ return 0; /* not a numeral */
+ switch (e->k) {
+ case VKINT:
+ if (v) setivalue(v, e->u.ival);
+ return 1;
+ case VKFLT:
+ if (v) setnvalue(v, e->u.nval);
+ return 1;
+ default: return 0;
+ }
}
@@ -293,9 +312,8 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
TValue *idx = luaH_set(L, fs->h, key);
Proto *f = fs->f;
int k, oldsize;
- if (ttisnumber(idx)) {
- lua_Number n = nvalue(idx);
- lua_number2int(k, n);
+ if (ttisinteger(idx)) {
+ k = ivalue(idx);
if (luaV_rawequalobj(&f->k[k], v))
return k;
/* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");
@@ -306,7 +324,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
k = fs->nk;
/* numerical value does not need GC barrier;
table has no metatable, so it does not need to invalidate cache */
- setnvalue(idx, cast_num(k));
+ setivalue(idx, k);
luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
setobj(L, &f->k[k], v);
@@ -323,20 +341,28 @@ int luaK_stringK (FuncState *fs, TString *s) {
}
-int luaK_numberK (FuncState *fs, lua_Number r) {
- int n;
- lua_State *L = fs->ls->L;
+/*
+** use userdata as key to avoid collision with float with same value;
+** conversion to 'void*' used only for hash, no "precision" problems
+*/
+int luaK_intK (FuncState *fs, lua_Integer n) {
+ TValue k, o;
+ setpvalue(&k, cast(void*, cast(size_t, n)));
+ setivalue(&o, n);
+ return addk(fs, &k, &o);
+}
+
+
+/*
+** Both NaN and -0.0 should not go to the constant table, as they have
+** problems with the hashing. (NaN is not ** a valid key,
+** -0.0 collides with +0.0.)
+*/
+static int luaK_numberK (FuncState *fs, lua_Number r) {
TValue o;
+ lua_assert(!luai_numisnan(NULL, r) && !isminuszero(r));
setnvalue(&o, r);
- if (r == 0 || luai_numisnan(NULL, r)) { /* handle -0 and NaN */
- /* use raw representation as key to avoid numeric problems */
- setsvalue(L, L->top++, luaS_newlstr(L, (char *)&r, sizeof(r)));
- n = addk(fs, L->top - 1, &o);
- L->top--;
- }
- else
- n = addk(fs, &o, &o); /* regular case */
- return n;
+ return addk(fs, &o, &o);
}
@@ -433,10 +459,14 @@ static void discharge2reg (FuncState *fs, expdesc *e, int reg) {
luaK_codek(fs, reg, e->u.info);
break;
}
- case VKNUM: {
+ case VKFLT: {
luaK_codek(fs, reg, luaK_numberK(fs, e->u.nval));
break;
}
+ case VKINT: {
+ luaK_codek(fs, reg, luaK_intK(fs, e->u.ival));
+ break;
+ }
case VRELOCABLE: {
Instruction *pc = &getcode(fs, e);
SETARG_A(*pc, reg);
@@ -538,12 +568,18 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
}
else break;
}
- case VKNUM: {
+ case VKINT: {
+ e->u.info = luaK_intK(fs, e->u.ival);
+ e->k = VK;
+ goto vk;
+ }
+ case VKFLT: {
e->u.info = luaK_numberK(fs, e->u.nval);
e->k = VK;
/* go through */
}
case VK: {
+ vk:
if (e->u.info <= MAXINDEXRK) /* constant fits in argC? */
return RKASK(e->u.info);
else break;
@@ -627,7 +663,7 @@ void luaK_goiftrue (FuncState *fs, expdesc *e) {
pc = e->u.info;
break;
}
- case VK: case VKNUM: case VTRUE: {
+ case VK: case VKFLT: case VKINT: case VTRUE: {
pc = NO_JUMP; /* always true; do nothing */
break;
}
@@ -672,7 +708,7 @@ static void codenot (FuncState *fs, expdesc *e) {
e->k = VTRUE;
break;
}
- case VK: case VKNUM: case VTRUE: {
+ case VK: case VKFLT: case VKINT: case VTRUE: {
e->k = VFALSE;
break;
}
@@ -711,21 +747,34 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {
- lua_Number r;
- if (!isnumeral(e1) || !isnumeral(e2)) return 0;
- if ((op == OP_DIV || op == OP_MOD) && e2->u.nval == 0)
- return 0; /* do not attempt to divide by 0 */
- r = luaO_arith(op - OP_ADD + LUA_OPADD, e1->u.nval, e2->u.nval);
- e1->u.nval = r;
+ TValue v1, v2, res;
+ lua_Integer i;
+ if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2))
+ return 0;
+ if (op == OP_IDIV &&
+ (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0))
+ return 0; /* avoid division by 0 and conversion errors */
+ if (op == OP_MOD && ttisinteger(&v1) && ttisinteger(&v2) && ivalue(&v2) == 0)
+ return 0; /* avoid module by 0 at compile time */
+ luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);
+ if (ttisinteger(&res)) {
+ e1->k = VKINT;
+ e1->u.ival = ivalue(&res);
+ }
+ else {
+ lua_Number n = fltvalue(&res);
+ if (luai_numisnan(NULL, n) || isminuszero(n))
+ return 0; /* folds neither NaN nor -0 */
+ e1->k = VKFLT;
+ e1->u.nval = n;
+ }
return 1;
}
static void codearith (FuncState *fs, OpCode op,
expdesc *e1, expdesc *e2, int line) {
- if (constfolding(op, e1, e2))
- return;
- else {
+ if (!constfolding(op, e1, e2)) { /* could not fold operation? */
int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;
int o1 = luaK_exp2RK(fs, e1);
if (o1 > o2) {
@@ -761,12 +810,10 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1,
void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
expdesc e2;
- e2.t = e2.f = NO_JUMP; e2.k = VKNUM; e2.u.nval = 0;
+ e2.t = e2.f = NO_JUMP; e2.k = VKFLT; e2.u.nval = 0;
switch (op) {
case OPR_MINUS: {
- if (isnumeral(e)) /* minus constant? */
- e->u.nval = luai_numunm(NULL, e->u.nval); /* fold it */
- else {
+ if (!constfolding(OP_UNM, e, e)) { /* cannot fold it? */
luaK_exp2anyreg(fs, e);
codearith(fs, OP_UNM, e, &e2, line);
}
@@ -797,9 +844,10 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
luaK_exp2nextreg(fs, v); /* operand must be on the `stack' */
break;
}
- case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
+ case OPR_ADD: case OPR_SUB:
+ case OPR_MUL: case OPR_DIV: case OPR_IDIV:
case OPR_MOD: case OPR_POW: {
- if (!isnumeral(v)) luaK_exp2RK(fs, v);
+ if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
break;
}
default: {
@@ -842,7 +890,7 @@ void luaK_posfix (FuncState *fs, BinOpr op,
break;
}
case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
- case OPR_MOD: case OPR_POW: {
+ case OPR_IDIV: case OPR_MOD: case OPR_POW: {
codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);
break;
}
diff --git a/src/lcode.h b/src/lcode.h
index 5a1fa9fe..07d451b4 100644
--- a/src/lcode.h
+++ b/src/lcode.h
@@ -1,5 +1,5 @@
/*
-** $Id: lcode.h,v 1.58 2011/08/30 16:26:41 roberto Exp $
+** $Id: lcode.h,v 1.60 2013/04/26 13:07:53 roberto Exp $
** Code generator for Lua
** See Copyright Notice in lua.h
*/
@@ -24,7 +24,7 @@
** grep "ORDER OPR" if you change these enums (ORDER OP)
*/
typedef enum BinOpr {
- OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_MOD, OPR_POW,
+ OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_IDIV, OPR_MOD, OPR_POW,
OPR_CONCAT,
OPR_EQ, OPR_LT, OPR_LE,
OPR_NE, OPR_GT, OPR_GE,
@@ -52,7 +52,7 @@ LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
LUAI_FUNC void luaK_reserveregs (FuncState *fs, int n);
LUAI_FUNC void luaK_checkstack (FuncState *fs, int n);
LUAI_FUNC int luaK_stringK (FuncState *fs, TString *s);
-LUAI_FUNC int luaK_numberK (FuncState *fs, lua_Number r);
+LUAI_FUNC int luaK_intK (FuncState *fs, lua_Integer n);
LUAI_FUNC void luaK_dischargevars (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
diff --git a/src/ldblib.c b/src/ldblib.c
index c0226945..30499a62 100644
--- a/src/ldblib.c
+++ b/src/ldblib.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldblib.c,v 1.132 2012/01/19 20:14:44 roberto Exp $
+** $Id: ldblib.c,v 1.133 2013/06/25 19:37:00 roberto Exp $
** Interface from Lua to its debug API
** See Copyright Notice in lua.h
*/
@@ -22,6 +22,18 @@
+static int db_numbits (lua_State *L) {
+ const char *s = luaL_checkstring(L, 1);
+ if (*s == 'i')
+ lua_pushinteger(L, sizeof(lua_Integer) * CHAR_BIT);
+ else if (*s == 'f')
+ lua_pushinteger(L, sizeof(lua_Number) * CHAR_BIT);
+ else
+ luaL_argerror(L, 1, lua_pushfstring(L, "invalid option '%s'", s));
+ return 1;
+}
+
+
static int db_getregistry (lua_State *L) {
lua_pushvalue(L, LUA_REGISTRYINDEX);
return 1;
@@ -379,6 +391,7 @@ static const luaL_Reg dblib[] = {
{"getregistry", db_getregistry},
{"getmetatable", db_getmetatable},
{"getupvalue", db_getupvalue},
+ {"numbits", db_numbits},
{"upvaluejoin", db_upvaluejoin},
{"upvalueid", db_upvalueid},
{"setuservalue", db_setuservalue},
diff --git a/src/ldebug.c b/src/ldebug.c
index 7e04f9d0..c9b88803 100644
--- a/src/ldebug.c
+++ b/src/ldebug.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.c,v 2.90 2012/08/16 17:34:28 roberto Exp $
+** $Id: ldebug.c,v 2.95 2013/05/06 17:21:59 roberto Exp $
** Debug Interface
** See Copyright Notice in lua.h
*/
@@ -453,6 +453,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
case OP_SUB: tm = TM_SUB; break;
case OP_MUL: tm = TM_MUL; break;
case OP_DIV: tm = TM_DIV; break;
+ case OP_IDIV: tm = TM_IDIV; break;
case OP_MOD: tm = TM_MOD; break;
case OP_POW: tm = TM_POW; break;
case OP_UNM: tm = TM_UNM; break;
@@ -497,10 +498,9 @@ static const char *getupvalname (CallInfo *ci, const TValue *o,
}
-l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+static const char *varinfo (lua_State *L, const TValue *o) {
+ const char *name;
CallInfo *ci = L->ci;
- const char *name = NULL;
- const char *t = objtypename(o);
const char *kind = NULL;
if (isLua(ci)) {
kind = getupvalname(ci, o, &name); /* check whether 'o' is an upvalue */
@@ -508,29 +508,40 @@ l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
kind = getobjname(ci_func(ci)->p, currentpc(ci),
cast_int(o - ci->u.l.base), &name);
}
- if (kind)
- luaG_runerror(L, "attempt to %s %s " LUA_QS " (a %s value)",
- op, kind, name, t);
- else
- luaG_runerror(L, "attempt to %s a %s value", op, t);
+ return (kind) ? luaO_pushfstring(L, " (%s " LUA_QS ")", kind, name) : "";
+}
+
+
+l_noret luaG_typeerror (lua_State *L, const TValue *o, const char *op) {
+ const char *t = objtypename(o);
+ luaG_runerror(L, "attempt to %s a %s value%s", op, t, varinfo(L, o));
}
-l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2) {
+l_noret luaG_concaterror (lua_State *L, const TValue *p1, const TValue *p2) {
if (ttisstring(p1) || ttisnumber(p1)) p1 = p2;
- lua_assert(!ttisstring(p1) && !ttisnumber(p2));
+ lua_assert(!ttisstring(p1) && !ttisnumber(p1));
luaG_typeerror(L, p1, "concatenate");
}
l_noret luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
- TValue temp;
- if (luaV_tonumber(p1, &temp) == NULL)
+ lua_Number temp;
+ if (!tonumber(p1, &temp))
p2 = p1; /* first operand is wrong */
luaG_typeerror(L, p2, "perform arithmetic on");
}
+l_noret luaG_tointerror (lua_State *L, const TValue *p1, const TValue *p2) {
+ lua_Integer temp;
+ if (!tointeger(p1, &temp))
+ p2 = p1;
+ luaG_runerror(L, "attempt to convert an out of range float%s to an integer",
+ varinfo(L, p2));
+}
+
+
l_noret luaG_ordererror (lua_State *L, const TValue *p1, const TValue *p2) {
const char *t1 = objtypename(p1);
const char *t2 = objtypename(p2);
@@ -578,3 +589,36 @@ l_noret luaG_runerror (lua_State *L, const char *fmt, ...) {
luaG_errormsg(L);
}
+
+void luaG_traceexec (lua_State *L) {
+ CallInfo *ci = L->ci;
+ lu_byte mask = L->hookmask;
+ int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
+ if (counthook)
+ resethookcount(L); /* reset count */
+ if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
+ ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
+ return; /* do not call hook again (VM yielded, so it did not move) */
+ }
+ if (counthook)
+ luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
+ if (mask & LUA_MASKLINE) {
+ 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); /* call line hook */
+ }
+ L->oldpc = ci->u.l.savedpc;
+ if (L->status == LUA_YIELD) { /* did hook yield? */
+ if (counthook)
+ L->hookcount = 1; /* undo decrement to zero */
+ ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
+ ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
+ ci->func = L->top - 1; /* protect stack below results */
+ luaD_throw(L, LUA_YIELD);
+ }
+}
+
diff --git a/src/ldebug.h b/src/ldebug.h
index fe39556b..c668e1e4 100644
--- a/src/ldebug.h
+++ b/src/ldebug.h
@@ -1,5 +1,5 @@
/*
-** $Id: ldebug.h,v 2.7 2011/10/07 20:45:19 roberto Exp $
+** $Id: ldebug.h,v 2.10 2013/05/06 17:19:11 roberto Exp $
** Auxiliary functions from Debug Interface module
** See Copyright Notice in lua.h
*/
@@ -23,12 +23,17 @@
LUAI_FUNC l_noret luaG_typeerror (lua_State *L, const TValue *o,
const char *opname);
-LUAI_FUNC l_noret luaG_concaterror (lua_State *L, StkId p1, StkId p2);
+LUAI_FUNC l_noret luaG_concaterror (lua_State *L, const TValue *p1,
+ const TValue *p2);
LUAI_FUNC l_noret luaG_aritherror (lua_State *L, const TValue *p1,
const TValue *p2);
+LUAI_FUNC l_noret luaG_tointerror (lua_State *L, const TValue *p1,
+ const TValue *p2);
LUAI_FUNC l_noret luaG_ordererror (lua_State *L, const TValue *p1,
const TValue *p2);
LUAI_FUNC l_noret luaG_runerror (lua_State *L, const char *fmt, ...);
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
+LUAI_FUNC void luaG_traceexec (lua_State *L);
+
#endif
diff --git a/src/ldo.c b/src/ldo.c
index aafa3dca..abf082d4 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldo.c,v 2.108 2012/10/01 14:05:04 roberto Exp $
+** $Id: ldo.c,v 2.109 2013/04/19 21:05:04 roberto Exp $
** Stack and Call structure of Lua
** See Copyright Notice in lua.h
*/
@@ -260,6 +260,7 @@ static StkId adjust_varargs (lua_State *L, Proto *p, int actual) {
StkId base, fixed;
lua_assert(actual >= nfixargs);
/* move fixed parameters to final position */
+ luaD_checkstack(L, p->maxstacksize); /* check again for new 'base' */
fixed = L->top - actual; /* first fixed argument */
base = L->top; /* final position of first argument */
for (i=0; i<nfixargs; i++) {
@@ -324,12 +325,18 @@ int luaD_precall (lua_State *L, StkId func, int nresults) {
case LUA_TLCL: { /* Lua function: prepare its call */
StkId base;
Proto *p = clLvalue(func)->p;
- luaD_checkstack(L, p->maxstacksize);
- func = restorestack(L, funcr);
n = cast_int(L->top - func) - 1; /* number of real arguments */
+ luaD_checkstack(L, p->maxstacksize);
for (; n < p->numparams; n++)
setnilvalue(L->top++); /* complete missing arguments */
- base = (!p->is_vararg) ? func + 1 : adjust_varargs(L, p, n);
+ if (!p->is_vararg) {
+ func = restorestack(L, funcr);
+ base = func + 1;
+ }
+ else {
+ base = adjust_varargs(L, p, n);
+ func = restorestack(L, funcr); /* previous call can change stack */
+ }
ci = next_ci(L); /* now 'enter' new function */
ci->nresults = nresults;
ci->func = func;
diff --git a/src/ldump.c b/src/ldump.c
index d5e6a47c..b3a25624 100644
--- a/src/ldump.c
+++ b/src/ldump.c
@@ -1,5 +1,5 @@
/*
-** $Id: ldump.c,v 2.17 2012/01/23 23:02:10 roberto Exp $
+** $Id: ldump.c,v 2.19 2013/04/26 18:48:35 roberto Exp $
** save precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -52,6 +52,11 @@ static void DumpNumber(lua_Number x, DumpState* D)
DumpVar(x,D);
}
+static void DumpInteger(lua_Integer x, DumpState* D)
+{
+ DumpVar(x,D);
+}
+
static void DumpVector(const void* b, int n, size_t size, DumpState* D)
{
DumpInt(n,D);
@@ -84,18 +89,21 @@ static void DumpConstants(const Proto* f, DumpState* D)
for (i=0; i<n; i++)
{
const TValue* o=&f->k[i];
- DumpChar(ttypenv(o),D);
- switch (ttypenv(o))
+ DumpChar(ttype(o),D);
+ switch (ttype(o))
{
case LUA_TNIL:
break;
case LUA_TBOOLEAN:
DumpChar(bvalue(o),D);
break;
- case LUA_TNUMBER:
- DumpNumber(nvalue(o),D);
+ case LUA_TNUMFLT:
+ DumpNumber(fltvalue(o),D);
+ break;
+ case LUA_TNUMINT:
+ DumpInteger(ivalue(o),D);
break;
- case LUA_TSTRING:
+ case LUA_TSHRSTR: case LUA_TLNGSTR:
DumpString(rawtsvalue(o),D);
break;
default: lua_assert(0);
diff --git a/src/lgc.c b/src/lgc.c
index 535e988a..5e305fb3 100644
--- a/src/lgc.c
+++ b/src/lgc.c
@@ -1,5 +1,5 @@
/*
-** $Id: lgc.c,v 2.140 2013/03/16 21:10:18 roberto Exp $
+** $Id: lgc.c,v 2.141 2013/04/26 18:26:49 roberto Exp $
** Garbage Collector
** See Copyright Notice in lua.h
*/
@@ -493,17 +493,24 @@ static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
static lu_mem traversestack (global_State *g, lua_State *th) {
+ int n = 0;
StkId o = th->stack;
if (o == NULL)
return 1; /* stack not completely built yet */
- for (; o < th->top; o++)
+ for (; o < th->top; o++) /* mark live elements in the stack */
markvalue(g, o);
if (g->gcstate == GCSatomic) { /* final traversal? */
StkId lim = th->stack + th->stacksize; /* real end of stack */
for (; o < lim; o++) /* clear not-marked stack slice */
setnilvalue(o);
}
- return sizeof(lua_State) + sizeof(TValue) * th->stacksize;
+ else { /* count call infos to compute size */
+ CallInfo *ci;
+ for (ci = &th->base_ci; ci != th->ci; ci = ci->next)
+ n++;
+ }
+ return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
+ sizeof(CallInfo) * n;
}
diff --git a/src/liolib.c b/src/liolib.c
index 3f80db19..2c6202af 100644
--- a/src/liolib.c
+++ b/src/liolib.c
@@ -1,17 +1,17 @@
/*
-** $Id: liolib.c,v 2.111 2013/03/21 13:57:27 roberto Exp $
+** $Id: liolib.c,v 2.114 2013/06/07 19:01:35 roberto Exp $
** Standard I/O (and system) library
** See Copyright Notice in lua.h
*/
/*
-** POSIX idiosyncrasy!
** This definition must come before the inclusion of 'stdio.h'; it
** should not affect non-POSIX systems
*/
#if !defined(_FILE_OFFSET_BITS)
-#define _FILE_OFFSET_BITS 64
+#define _LARGEFILE_SOURCE 1
+#define _FILE_OFFSET_BITS 64
#endif
@@ -80,36 +80,37 @@
/*
** {======================================================
-** lua_fseek/lua_ftell: configuration for longer offsets
+** lua_fseek: configuration for longer offsets
** =======================================================
*/
-#if !defined(lua_fseek) /* { */
+#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */
-#if defined(LUA_USE_POSIX)
+#if defined(LUA_USE_POSIX) /* { */
#define l_fseek(f,o,w) fseeko(f,o,w)
#define l_ftell(f) ftello(f)
#define l_seeknum off_t
#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
- && defined(_MSC_VER) && (_MSC_VER >= 1400)
+ && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
/* Windows (but not DDK) and Visual C++ 2005 or higher */
#define l_fseek(f,o,w) _fseeki64(f,o,w)
#define l_ftell(f) _ftelli64(f)
#define l_seeknum __int64
-#else
+#endif /* } */
+#endif /* } */
+
+
+#if !defined(l_fseek) /* default definitions */
#define l_fseek(f,o,w) fseek(f,o,w)
#define l_ftell(f) ftell(f)
#define l_seeknum long
-
#endif
-#endif /* } */
-
/* }====================================================== */
@@ -346,6 +347,19 @@ static int io_lines (lua_State *L) {
*/
+static int read_integer (lua_State *L, FILE *f) {
+ lua_Integer d;
+ if (fscanf(f, LUA_INTEGER_SCAN, &d) == 1) {
+ lua_pushinteger(L, d);
+ return 1;
+ }
+ else {
+ lua_pushnil(L); /* "result" to be removed */
+ return 0; /* read fails */
+ }
+}
+
+
static int read_number (lua_State *L, FILE *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
@@ -441,6 +455,9 @@ static int g_read (lua_State *L, FILE *f, int first) {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
+ case 'i': /* integer */
+ success = read_integer(L, f);
+ break;
case 'n': /* number */
success = read_number(L, f);
break;
@@ -516,8 +533,10 @@ static int g_write (lua_State *L, FILE *f, int arg) {
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
- status = status &&
- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
+ int len = lua_isinteger(L, arg)
+ ? fprintf(f, LUA_INTEGER_FMT, lua_tointeger(L, arg))
+ : fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg));
+ status = status && (len > 0);
}
else {
size_t l;
diff --git a/src/llex.c b/src/llex.c
index 1a32e348..e1a54c7d 100644
--- a/src/llex.c
+++ b/src/llex.c
@@ -1,5 +1,5 @@
/*
-** $Id: llex.c,v 2.63 2013/03/16 21:10:18 roberto Exp $
+** $Id: llex.c,v 2.67 2013/06/19 14:27:00 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -38,8 +38,8 @@ static const char *const luaX_tokens [] = {
"end", "false", "for", "function", "goto", "if",
"in", "local", "nil", "not", "or", "repeat",
"return", "then", "true", "until", "while",
- "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
- "<number>", "<name>", "<string>"
+ "//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",
+ "<number>", "<number>", "<name>", "<string>"
};
@@ -53,7 +53,7 @@ static void save (LexState *ls, int c) {
Mbuffer *b = ls->buff;
if (luaZ_bufflen(b) + 1 > luaZ_sizebuffer(b)) {
size_t newsize;
- if (luaZ_sizebuffer(b) >= MAX_SIZET/2)
+ if (luaZ_sizebuffer(b) >= MAX_SIZE/2)
lexerror(ls, "lexical element too long", 0);
newsize = luaZ_sizebuffer(b) * 2;
luaZ_resizebuffer(ls->L, b, newsize);
@@ -90,9 +90,8 @@ const char *luaX_token2str (LexState *ls, int token) {
static const char *txtToken (LexState *ls, int token) {
switch (token) {
- case TK_NAME:
- case TK_STRING:
- case TK_NUMBER:
+ case TK_NAME: case TK_STRING:
+ case TK_FLT: case TK_INT:
save(ls, '\0');
return luaO_pushfstring(ls->L, LUA_QS, luaZ_buffer(ls->buff));
default:
@@ -216,7 +215,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
if (!buff2d(ls->buff, &seminfo->r)) {
/* format error with correct decimal point: no more options */
buffreplace(ls, ls->decpoint, '.'); /* undo change (for error message) */
- lexerror(ls, "malformed number", TK_NUMBER);
+ lexerror(ls, "malformed number", TK_FLT);
}
}
@@ -224,9 +223,10 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) {
/* LUA_NUMBER */
/*
** this function is quite liberal in what it accepts, as 'luaO_str2d'
-** will reject ill-formed numerals.
+** will reject ill-formed numerals. 'isf' means the numeral is not
+** an integer (it has a dot or an exponent).
*/
-static void read_numeral (LexState *ls, SemInfo *seminfo) {
+static int read_numeral (LexState *ls, SemInfo *seminfo, int isf) {
const char *expo = "Ee";
int first = ls->current;
lua_assert(lisdigit(ls->current));
@@ -234,16 +234,31 @@ static void read_numeral (LexState *ls, SemInfo *seminfo) {
if (first == '0' && check_next(ls, "Xx")) /* hexadecimal? */
expo = "Pp";
for (;;) {
- if (check_next(ls, expo)) /* exponent part? */
+ if (check_next(ls, expo)) { /* exponent part? */
check_next(ls, "+-"); /* optional exponent sign */
- if (lisxdigit(ls->current) || ls->current == '.')
+ isf = 1;
+ }
+ if (lisxdigit(ls->current))
+ save_and_next(ls);
+ else if (ls->current == '.') {
save_and_next(ls);
- else break;
+ isf = 1;
+ }
+ else break;
}
save(ls, '\0');
- buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
- if (!buff2d(ls->buff, &seminfo->r)) /* format error? */
- trydecpoint(ls, seminfo); /* try to update decimal point separator */
+ if (!isf) {
+ if (!luaO_str2int(luaZ_buffer(ls->buff), luaZ_bufflen(ls->buff) - 1,
+ &seminfo->i))
+ lexerror(ls, "malformed number", TK_INT);
+ return TK_INT;
+ }
+ else {
+ buffreplace(ls, '.', ls->decpoint); /* follow locale for decimal point */
+ if (!buff2d(ls->buff, &seminfo->r)) /* format error? */
+ trydecpoint(ls, seminfo); /* try to update decimal point separator */
+ return TK_FLT;
+ }
}
@@ -450,6 +465,11 @@ static int llex (LexState *ls, SemInfo *seminfo) {
if (ls->current != '=') return '>';
else { next(ls); return TK_GE; }
}
+ case '/': {
+ next(ls);
+ if (ls->current != '/') return '/';
+ else { next(ls); return TK_IDIV; }
+ }
case '~': {
next(ls);
if (ls->current != '=') return '~';
@@ -472,12 +492,11 @@ static int llex (LexState *ls, SemInfo *seminfo) {
else return TK_CONCAT; /* '..' */
}
else if (!lisdigit(ls->current)) return '.';
- /* else go through */
+ else return read_numeral(ls, seminfo, 1);
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': {
- read_numeral(ls, seminfo);
- return TK_NUMBER;
+ return read_numeral(ls, seminfo, 0);
}
case EOZ: {
return TK_EOS;
diff --git a/src/llex.h b/src/llex.h
index 9ca8a299..7cba9906 100644
--- a/src/llex.h
+++ b/src/llex.h
@@ -1,5 +1,5 @@
/*
-** $Id: llex.h,v 1.72 2011/11/30 12:43:51 roberto Exp $
+** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp $
** Lexical Analyzer
** See Copyright Notice in lua.h
*/
@@ -26,8 +26,9 @@ enum RESERVED {
TK_GOTO, TK_IF, TK_IN, TK_LOCAL, TK_NIL, TK_NOT, TK_OR, TK_REPEAT,
TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
/* other terminal symbols */
- TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE, TK_DBCOLON, TK_EOS,
- TK_NUMBER, TK_NAME, TK_STRING
+ TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
+ TK_DBCOLON, TK_EOS,
+ TK_FLT, TK_INT, TK_NAME, TK_STRING
};
/* number of reserved words */
@@ -36,6 +37,7 @@ enum RESERVED {
typedef union {
lua_Number r;
+ lua_Integer i;
TString *ts;
} SemInfo; /* semantics information */
diff --git a/src/llimits.h b/src/llimits.h
index 1b8c79bd..c4416f89 100644
--- a/src/llimits.h
+++ b/src/llimits.h
@@ -1,5 +1,5 @@
/*
-** $Id: llimits.h,v 1.103 2013/02/20 14:08:56 roberto Exp $
+** $Id: llimits.h,v 1.108 2013/06/19 14:27:00 roberto Exp $
** Limits, basic types, and some other `installation-dependent' definitions
** See Copyright Notice in lua.h
*/
@@ -27,8 +27,14 @@ typedef LUAI_MEM l_mem;
typedef unsigned char lu_byte;
+/* maximum value for size_t */
#define MAX_SIZET ((size_t)(~(size_t)0)-2)
+/* maximum size visible for Lua (must be representable in a lua_Integer */
+#define MAX_SIZE (sizeof(size_t) <= sizeof(lua_Integer) ? MAX_SIZET \
+ : (size_t)(~(lua_Unsigned)0)-2)
+
+
#define MAX_LUMEM ((lu_mem)(~(lu_mem)0)-2)
#define MAX_LMEM ((l_mem) ((MAX_LUMEM >> 1) - 2))
@@ -36,6 +42,12 @@ typedef unsigned char lu_byte;
#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
+
+/* minimum and maximum values for lua_Integer */
+#define MAX_INTEGER ((lua_Integer)(~(lua_Unsigned)0 >> 1))
+#define MIN_INTEGER (~MAX_INTEGER)
+
+
/*
** conversion of pointer to integer
** this is for hashing only; there is no problem if the integer
@@ -96,6 +108,8 @@ typedef LUAI_UACNUMBER l_uacNumber;
#define cast_num(i) cast(lua_Number, (i))
#define cast_int(i) cast(int, (i))
#define cast_uchar(i) cast(unsigned char, (i))
+#define cast_integer(i) cast(lua_Integer, (i))
+#define cast_unsigned(i) cast(lua_Unsigned, (i))
/*
@@ -190,103 +204,6 @@ typedef lu_int32 Instruction;
#define luai_userstateyield(L,n) ((void)L)
#endif
-/*
-** lua_number2int is a macro to convert lua_Number to int.
-** lua_number2integer is a macro to convert lua_Number to lua_Integer.
-** lua_number2unsigned is a macro to convert a lua_Number to a lua_Unsigned.
-** lua_unsigned2number is a macro to convert a lua_Unsigned to a lua_Number.
-** luai_hashnum is a macro to hash a lua_Number value into an integer.
-** The hash must be deterministic and give reasonable values for
-** both small and large values (outside the range of integers).
-*/
-
-#if defined(MS_ASMTRICK) || defined(LUA_MSASMTRICK) /* { */
-/* trick with Microsoft assembler for X86 */
-
-#define lua_number2int(i,n) __asm {__asm fld n __asm fistp i}
-#define lua_number2integer(i,n) lua_number2int(i, n)
-#define lua_number2unsigned(i,n) \
- {__int64 l; __asm {__asm fld n __asm fistp l} i = (unsigned int)l;}
-
-
-#elif defined(LUA_IEEE754TRICK) /* }{ */
-/* the next trick should work on any machine using IEEE754 with
- a 32-bit int type */
-
-union luai_Cast { double l_d; LUA_INT32 l_p[2]; };
-
-#if !defined(LUA_IEEEENDIAN) /* { */
-#define LUAI_EXTRAIEEE \
- static const union luai_Cast ieeeendian = {-(33.0 + 6755399441055744.0)};
-#define LUA_IEEEENDIANLOC (ieeeendian.l_p[1] == 33)
-#else
-#define LUA_IEEEENDIANLOC LUA_IEEEENDIAN
-#define LUAI_EXTRAIEEE /* empty */
-#endif /* } */
-
-#define lua_number2int32(i,n,t) \
- { LUAI_EXTRAIEEE \
- volatile union luai_Cast u; u.l_d = (n) + 6755399441055744.0; \
- (i) = (t)u.l_p[LUA_IEEEENDIANLOC]; }
-
-#define luai_hashnum(i,n) \
- { volatile union luai_Cast u; u.l_d = (n) + 1.0; /* avoid -0 */ \
- (i) = u.l_p[0]; (i) += u.l_p[1]; } /* add double bits for his hash */
-
-#define lua_number2int(i,n) lua_number2int32(i, n, int)
-#define lua_number2unsigned(i,n) lua_number2int32(i, n, lua_Unsigned)
-
-/* the trick can be expanded to lua_Integer when it is a 32-bit value */
-#if defined(LUA_IEEELL)
-#define lua_number2integer(i,n) lua_number2int32(i, n, lua_Integer)
-#endif
-
-#endif /* } */
-
-
-/* the following definitions always work, but may be slow */
-
-#if !defined(lua_number2int)
-#define lua_number2int(i,n) ((i)=(int)(n))
-#endif
-
-#if !defined(lua_number2integer)
-#define lua_number2integer(i,n) ((i)=(lua_Integer)(n))
-#endif
-
-#if !defined(lua_number2unsigned) /* { */
-/* the following definition assures proper modulo behavior */
-#if defined(LUA_NUMBER_DOUBLE) || defined(LUA_NUMBER_FLOAT)
-#include <math.h>
-#define SUPUNSIGNED ((lua_Number)(~(lua_Unsigned)0) + 1)
-#define lua_number2unsigned(i,n) \
- ((i)=(lua_Unsigned)((n) - floor((n)/SUPUNSIGNED)*SUPUNSIGNED))
-#else
-#define lua_number2unsigned(i,n) ((i)=(lua_Unsigned)(n))
-#endif
-#endif /* } */
-
-
-#if !defined(lua_unsigned2number)
-/* on several machines, coercion from unsigned to double is slow,
- so it may be worth to avoid */
-#define lua_unsigned2number(u) \
- (((u) <= (lua_Unsigned)INT_MAX) ? (lua_Number)(int)(u) : (lua_Number)(u))
-#endif
-
-
-
-#if defined(ltable_c) && !defined(luai_hashnum)
-
-#include <float.h>
-#include <math.h>
-
-#define luai_hashnum(i,n) { int e; \
- n = l_mathop(frexp)(n, &e) * (lua_Number)(INT_MAX - DBL_MAX_EXP); \
- lua_number2int(i, n); i += e; }
-
-#endif
-
/*
diff --git a/src/lmathlib.c b/src/lmathlib.c
index a49f1fd2..f26b05ca 100644
--- a/src/lmathlib.c
+++ b/src/lmathlib.c
@@ -1,5 +1,5 @@
/*
-** $Id: lmathlib.c,v 1.83 2013/03/07 18:21:32 roberto Exp $
+** $Id: lmathlib.c,v 1.90 2013/07/03 17:23:19 roberto Exp $
** Standard mathematical library
** See Copyright Notice in lua.h
*/
@@ -22,7 +22,6 @@
#define RADIANS_PER_DEGREE ((lua_Number)(PI/180.0))
-
static int math_abs (lua_State *L) {
lua_pushnumber(L, l_mathop(fabs)(luaL_checknumber(L, 1)));
return 1;
@@ -89,20 +88,40 @@ static int math_floor (lua_State *L) {
return 1;
}
+static int math_ifloor (lua_State *L) {
+ int valid;
+ lua_Integer n = lua_tointegerx(L, 1, &valid);
+ if (valid)
+ lua_pushinteger(L, n);
+ else {
+ luaL_checktype(L, 1, LUA_TNUMBER); /* error if not a number */
+ lua_pushnil(L); /* number with invalid integer value */
+ }
+ return 1;
+}
+
static int math_fmod (lua_State *L) {
lua_pushnumber(L, l_mathop(fmod)(luaL_checknumber(L, 1),
luaL_checknumber(L, 2)));
return 1;
}
+/*
+** next function does not use 'modf', avoiding problems with 'double*'
+** (which is not compatible with 'float*') when lua_Number is not
+** 'double'.
+*/
static int math_modf (lua_State *L) {
- lua_Number ip;
- lua_Number fp = l_mathop(modf)(luaL_checknumber(L, 1), &ip);
+ lua_Number n = luaL_checknumber(L, 1);
+ /* integer part (rounds toward zero) */
+ lua_Number ip = (n < 0) ? -l_mathop(floor)(-n) : l_mathop(floor)(n);
lua_pushnumber(L, ip);
- lua_pushnumber(L, fp);
+ /* fractionary part (test handles inf/-inf) */
+ lua_pushnumber(L, (n == ip) ? 0.0 : (n - ip));
return 2;
}
+
static int math_sqrt (lua_State *L) {
lua_pushnumber(L, l_mathop(sqrt)(luaL_checknumber(L, 1)));
return 1;
@@ -199,26 +218,28 @@ static int math_random (lua_State *L) {
/* the `%' avoids the (rare) case of r==1, and is needed also because on
some systems (SunOS!) `rand()' may return a value larger than RAND_MAX */
lua_Number r = (lua_Number)(rand()%RAND_MAX) / (lua_Number)RAND_MAX;
+ lua_Integer low, up;
switch (lua_gettop(L)) { /* check number of arguments */
case 0: { /* no arguments */
lua_pushnumber(L, r); /* Number between 0 and 1 */
- break;
+ return 1;
}
case 1: { /* only upper limit */
- lua_Number u = luaL_checknumber(L, 1);
- luaL_argcheck(L, (lua_Number)1.0 <= u, 1, "interval is empty");
- lua_pushnumber(L, l_mathop(floor)(r*u) + (lua_Number)(1.0)); /* [1, u] */
+ low = 1;
+ up = luaL_checkinteger(L, 1);
break;
}
case 2: { /* lower and upper limits */
- lua_Number l = luaL_checknumber(L, 1);
- lua_Number u = luaL_checknumber(L, 2);
- luaL_argcheck(L, l <= u, 2, "interval is empty");
- lua_pushnumber(L, l_mathop(floor)(r*(u-l+1)) + l); /* [l, u] */
+ low = luaL_checkinteger(L, 1);
+ up = luaL_checkinteger(L, 2);
break;
}
default: return luaL_error(L, "wrong number of arguments");
}
+ /* random integer in the interval [low, up] */
+ up++; /* change interval to [low, up) */
+ luaL_argcheck(L, up - low > 0, 1, "interval is empty");
+ lua_pushinteger(L, (lua_Integer)(r * (lua_Number)(up - low)) + low);
return 1;
}
@@ -230,6 +251,13 @@ static int math_randomseed (lua_State *L) {
}
+static int math_isfloat (lua_State *L) {
+ luaL_checkany(L, 1);
+ lua_pushboolean(L, (lua_type(L, 1) == LUA_TNUMBER && !lua_isinteger(L, 1)));
+ return 1;
+}
+
+
static const luaL_Reg mathlib[] = {
{"abs", math_abs},
{"acos", math_acos},
@@ -242,8 +270,10 @@ static const luaL_Reg mathlib[] = {
{"deg", math_deg},
{"exp", math_exp},
{"floor", math_floor},
+ {"ifloor", math_ifloor},
{"fmod", math_fmod},
{"frexp", math_frexp},
+ {"isfloat", math_isfloat},
{"ldexp", math_ldexp},
#if defined(LUA_COMPAT_LOG10)
{"log10", math_log10},
diff --git a/src/lobject.c b/src/lobject.c
index c152785a..edb0efeb 100644
--- a/src/lobject.c
+++ b/src/lobject.c
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.c,v 2.58 2013/02/20 14:08:56 roberto Exp $
+** $Id: lobject.c,v 2.67 2013/06/25 18:58:32 roberto Exp $
** Some generic functions over Lua objects
** See Copyright Notice in lua.h
*/
@@ -70,7 +70,21 @@ int luaO_ceillog2 (unsigned int x) {
}
-lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
+static lua_Integer intarith (lua_State *L, int op, lua_Integer v1,
+ lua_Integer v2) {
+ switch (op) {
+ case LUA_OPADD: return intop(+, v1, v2);
+ case LUA_OPSUB:return intop(-, v1, v2);
+ case LUA_OPMUL:return intop(*, v1, v2);
+ case LUA_OPMOD: return luaV_mod(L, v1, v2);
+ case LUA_OPPOW: return luaV_pow(v1, v2);
+ case LUA_OPUNM: return -v1;
+ default: lua_assert(0); return 0;
+ }
+}
+
+
+static lua_Number numarith (int op, lua_Number v1, lua_Number v2) {
switch (op) {
case LUA_OPADD: return luai_numadd(NULL, v1, v2);
case LUA_OPSUB: return luai_numsub(NULL, v1, v2);
@@ -84,17 +98,41 @@ lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2) {
}
+void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
+ TValue *res) {
+ if (op == LUA_OPIDIV) { /* operates only on integers */
+ lua_Integer i1; lua_Integer i2;
+ if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
+ setivalue(res, luaV_div(L, i1, i2));
+ return;
+ }
+ /* else go to the end */
+ }
+ else { /* other operations */
+ lua_Number n1; lua_Number n2;
+ if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV &&
+ (op != LUA_OPPOW || ivalue(p2) >= 0)) {
+ setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
+ return;
+ }
+ else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
+ setnvalue(res, numarith(op, n1, n2));
+ return;
+ }
+ /* else go to the end */
+ }
+ /* could not perform raw operation; try metmethod */
+ lua_assert(L != NULL); /* cannot fail when folding (compile time) */
+ luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
+}
+
+
int luaO_hexavalue (int c) {
if (lisdigit(c)) return c - '0';
else return ltolower(c) - 'a' + 10;
}
-#if !defined(lua_strx2number)
-
-#include <math.h>
-
-
static int isneg (const char **s) {
if (**s == '-') { (*s)++; return 1; }
else if (**s == '+') (*s)++;
@@ -102,52 +140,81 @@ static int isneg (const char **s) {
}
-static lua_Number readhexa (const char **s, lua_Number r, int *count) {
- for (; lisxdigit(cast_uchar(**s)); (*s)++) { /* read integer part */
- r = (r * cast_num(16.0)) + cast_num(luaO_hexavalue(cast_uchar(**s)));
- (*count)++;
- }
- return r;
-}
+/*
+** lua_strx2number converts an hexadecimal numeric string to a number.
+** In C99, 'strtod' does 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.
+*/
+#if defined(LUA_USE_STRTODHEX)
+#define lua_strx2number(s,p) lua_str2number(s,p)
+#endif
+
+
+#if !defined(lua_strx2number)
+
+#include <math.h>
+/* maximum number of significant digits to read (to avoid overflows
+ even with single floats) */
+#define MAXSIGDIG 30
+
/*
** 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;
+ lua_Number r = 0.0; /* result (accumulator) */
+ int sigdig = 0; /* number of significant digits */
+ int nosigdig = 0; /* number of non-significant digits */
+ int e = 0; /* exponent correction */
int neg = 0; /* 1 if number is negative */
+ int dot = 0; /* true after seen a dot */
*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 */
+ for (s += 2; ; s++) { /* skip '0x' and read numeral */
+ if (*s == '.') {
+ if (dot) break; /* second dot? stop loop */
+ else dot = 1;
+ }
+ else if (lisxdigit(cast_uchar(*s))) {
+ if (sigdig == 0 && *s == '0') { /* non-significant zero? */
+ nosigdig++;
+ if (dot) e--; /* zero after dot? correct exponent */
+ }
+ else {
+ if (++sigdig <= MAXSIGDIG) { /* can read it without overflow? */
+ r = (r * cast_num(16.0)) + luaO_hexavalue(cast_uchar(*s));
+ if (dot) e--; /* decimal digit */
+ }
+ else /* too many digits; ignore */
+ if (!dot) e++; /* still count it for exponent */
+ }
+ }
+ else break; /* neither a dot nor a digit */
}
- if (i == 0 && e == 0)
- return 0.0; /* invalid format (no digit) */
- e *= -4; /* each fractional digit divides value by 2^-4 */
+ if (nosigdig + sigdig == 0) /* no digits? */
+ return 0.0; /* invalid format */
*endptr = cast(char *, s); /* valid up to here */
+ e *= 4; /* each digit multiplies/divides value by 2^4 */
if (*s == 'p' || *s == 'P') { /* exponent part? */
- int exp1 = 0;
- int neg1;
+ int exp1 = 0; /* exponent value */
+ int neg1; /* exponent signal */
s++; /* skip 'p' */
neg1 = isneg(&s); /* signal */
if (!lisdigit(cast_uchar(*s)))
- goto ret; /* must have at least one digit */
+ return 0.0; /* invalid; 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 */
}
- *endptr = cast(char *, s); /* valid up to here */
- ret:
if (neg) r = -r;
return l_mathop(ldexp)(r, e);
}
@@ -169,6 +236,36 @@ int luaO_str2d (const char *s, size_t len, lua_Number *result) {
}
+int luaO_str2int (const char *s, size_t len, lua_Integer *result) {
+ const char *ends = s + len;
+ lua_Unsigned a = 0;
+ int empty = 1;
+ int neg;
+ while (lisspace(cast_uchar(*s))) s++; /* skip initial spaces */
+ neg = isneg(&s);
+ if (s[0] == '0' &&
+ (s[1] == 'x' || s[1] == 'X')) { /* hexa? */
+ s += 2; /* skip '0x' */
+ for (; lisxdigit(cast_uchar(*s)); s++) {
+ a = a * 16 + luaO_hexavalue(cast_uchar(*s));
+ empty = 0;
+ }
+ }
+ else { /* decimal */
+ for (; lisdigit(cast_uchar(*s)); s++) {
+ a = a * 10 + luaO_hexavalue(cast_uchar(*s));
+ empty = 0;
+ }
+ }
+ while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */
+ if (empty || s != ends) return 0; /* something wrong in the numeral */
+ else {
+ if (neg) *result = -cast(lua_Integer, a);
+ else *result = cast(lua_Integer, a);
+ return 1;
+ }
+}
+
static void pushstr (lua_State *L, const char *str, size_t l) {
setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
@@ -197,7 +294,11 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
break;
}
case 'd': {
- setnvalue(L->top++, cast_num(va_arg(argp, int)));
+ setivalue(L->top++, cast_int(va_arg(argp, int)));
+ break;
+ }
+ case 'I': {
+ setivalue(L->top++, cast_integer(va_arg(argp, lua_Integer)));
break;
}
case 'f': {
diff --git a/src/lobject.h b/src/lobject.h
index dd23b914..55b4e240 100644
--- a/src/lobject.h
+++ b/src/lobject.h
@@ -1,5 +1,5 @@
/*
-** $Id: lobject.h,v 2.71 2012/09/11 18:21:44 roberto Exp $
+** $Id: lobject.h,v 2.78 2013/05/14 15:59:04 roberto Exp $
** Type definitions for Lua objects
** See Copyright Notice in lua.h
*/
@@ -57,6 +57,11 @@
#define LUA_TLNGSTR (LUA_TSTRING | (1 << 4)) /* long strings */
+/* Variant tags for numbers */
+#define LUA_TNUMFLT (LUA_TNUMBER | (0 << 4)) /* float numbers */
+#define LUA_TNUMINT (LUA_TNUMBER | (1 << 4)) /* integer numbers */
+
+
/* Bit mark for collectable types */
#define BIT_ISCOLLECTABLE (1 << 6)
@@ -92,8 +97,6 @@ typedef struct GCheader {
typedef union Value Value;
-#define numfield lua_Number n; /* numbers */
-
/*
@@ -111,7 +114,6 @@ typedef struct lua_TValue TValue;
#define val_(o) ((o)->value_)
-#define num_(o) (val_(o).n)
/* raw type tag of a TValue */
@@ -124,13 +126,15 @@ typedef struct lua_TValue TValue;
#define ttype(o) (rttype(o) & 0x3F)
/* type tag of a TValue with no variants (bits 0-3) */
-#define ttypenv(o) (novariant(rttype(o)))
+#define ttnov(o) (novariant(rttype(o)))
/* Macros to test type */
#define checktag(o,t) (rttype(o) == (t))
-#define checktype(o,t) (ttypenv(o) == (t))
-#define ttisnumber(o) checktag((o), LUA_TNUMBER)
+#define checktype(o,t) (ttnov(o) == (t))
+#define ttisnumber(o) checktype((o), LUA_TNUMBER)
+#define ttisfloat(o) checktag((o), LUA_TNUMFLT)
+#define ttisinteger(o) checktag((o), LUA_TNUMINT)
#define ttisnil(o) checktag((o), LUA_TNIL)
#define ttisboolean(o) checktag((o), LUA_TBOOLEAN)
#define ttislightuserdata(o) checktag((o), LUA_TLIGHTUSERDATA)
@@ -147,10 +151,10 @@ typedef struct lua_TValue TValue;
#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 nvalue(o) check_exp(ttisnumber(o), num_(o))
+#define ivalue(o) check_exp(ttisinteger(o), val_(o).i)
+#define fltvalue(o) check_exp(ttisfloat(o), val_(o).n)
#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)
@@ -185,7 +189,10 @@ typedef struct lua_TValue TValue;
#define settt_(o,t) ((o)->tt_=(t))
#define setnvalue(obj,x) \
- { TValue *io=(obj); num_(io)=(x); settt_(io, LUA_TNUMBER); }
+ { TValue *io=(obj); val_(io).n=(x); settt_(io, LUA_TNUMFLT); }
+
+#define setivalue(obj,x) \
+ { TValue *io=(obj); val_(io).i=(x); settt_(io, LUA_TNUMINT); }
#define setnilvalue(obj) settt_(obj, LUA_TNIL)
@@ -267,115 +274,6 @@ typedef struct lua_TValue TValue;
#define luai_checknum(L,o,c) { /* empty */ }
-/*
-** {======================================================
-** NaN Trick
-** =======================================================
-*/
-#if defined(LUA_NANTRICK)
-
-/*
-** 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')
-*/
-
-/* allows for external implementation for part of the trick */
-#if !defined(NNMARK) /* { */
-
-
-#if !defined(LUA_IEEEENDIAN)
-#error option 'LUA_NANTRICK' needs 'LUA_IEEEENDIAN'
-#endif
-
-
-#define NNMARK 0x7FF7A500
-#define NNMASK 0x7FFFFF00
-
-#undef TValuefields
-#undef NILCONSTANT
-
-#if (LUA_IEEEENDIAN == 0) /* { */
-
-/* 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__)
-
-#else /* }{ */
-
-/* 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__)
-
-#endif /* } */
-
-#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
-#undef checktype
-#define checktag(o,t) (tt_(o) == tag2tt(t))
-#define checktype(o,t) (ctb(tt_(o) | VARBITS) == ctb(tag2tt(t) | VARBITS))
-
-#undef ttisequal
-#define ttisequal(o1,o2) \
- (ttisnumber(o1) ? ttisnumber(o2) : (tt_(o1) == tt_(o2)))
-
-
-#undef luai_checknum
-#define luai_checknum(L,o,c) { if (!ttisnumber(o)) c; }
-
-#endif
-/* }====================================================== */
-
/*
@@ -390,7 +288,8 @@ union Value {
void *p; /* light userdata */
int b; /* booleans */
lua_CFunction f; /* light C functions */
- numfield /* numbers */
+ lua_Integer i; /* integer numbers */
+ lua_Number n; /* float numbers */
};
@@ -594,8 +493,10 @@ LUAI_DDEC const TValue luaO_nilobject_;
LUAI_FUNC int luaO_int2fb (unsigned int x);
LUAI_FUNC int luaO_fb2int (int x);
LUAI_FUNC int luaO_ceillog2 (unsigned int x);
-LUAI_FUNC lua_Number luaO_arith (int op, lua_Number v1, lua_Number v2);
+LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
+ const TValue *p2, TValue *res);
LUAI_FUNC int luaO_str2d (const char *s, size_t len, lua_Number *result);
+LUAI_FUNC int luaO_str2int (const char *s, size_t len, lua_Integer *result);
LUAI_FUNC int luaO_hexavalue (int c);
LUAI_FUNC const char *luaO_pushvfstring (lua_State *L, const char *fmt,
va_list argp);
diff --git a/src/lopcodes.c b/src/lopcodes.c
index ef736927..0bd7a3e8 100644
--- a/src/lopcodes.c
+++ b/src/lopcodes.c
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.c,v 1.49 2012/05/14 13:34:18 roberto Exp $
+** $Id: lopcodes.c,v 1.50 2013/04/26 13:07:53 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -32,6 +32,7 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = {
"SUB",
"MUL",
"DIV",
+ "IDIV",
"MOD",
"POW",
"UNM",
@@ -80,6 +81,7 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = {
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
+ ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
diff --git a/src/lopcodes.h b/src/lopcodes.h
index 07d2b3f3..6c27b27a 100644
--- a/src/lopcodes.h
+++ b/src/lopcodes.h
@@ -1,5 +1,5 @@
/*
-** $Id: lopcodes.h,v 1.142 2011/07/15 12:50:29 roberto Exp $
+** $Id: lopcodes.h,v 1.143 2013/04/26 13:07:53 roberto Exp $
** Opcodes for Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -188,6 +188,7 @@ OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
+OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
OP_UNM,/* A B R(A) := -R(B) */
diff --git a/src/loslib.c b/src/loslib.c
index 5170fd0d..6d59bc39 100644
--- a/src/loslib.c
+++ b/src/loslib.c
@@ -1,5 +1,5 @@
/*
-** $Id: loslib.c,v 1.40 2012/10/19 15:54:02 roberto Exp $
+** $Id: loslib.c,v 1.41 2013/05/14 15:57:11 roberto Exp $
** Standard Operating System library
** See Copyright Notice in lua.h
*/
@@ -194,7 +194,7 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) {
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));
+ time_t t = luaL_opt(L, (time_t)luaL_checkinteger, 2, time(NULL));
struct tm tmr, *stm;
if (*s == '!') { /* UTC? */
stm = l_gmtime(&t, &tmr);
@@ -258,14 +258,14 @@ static int os_time (lua_State *L) {
if (t == (time_t)(-1))
lua_pushnil(L);
else
- lua_pushnumber(L, (lua_Number)t);
+ lua_pushinteger(L, t);
return 1;
}
static int os_difftime (lua_State *L) {
- lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
- (time_t)(luaL_optnumber(L, 2, 0))));
+ lua_pushnumber(L, difftime((time_t)(luaL_checkinteger(L, 1)),
+ (time_t)(luaL_optinteger(L, 2, 0))));
return 1;
}
diff --git a/src/lparser.c b/src/lparser.c
index d8f5b4ff..e8a6b8ef 100644
--- a/src/lparser.c
+++ b/src/lparser.c
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.c,v 2.130 2013/02/06 13:37:39 roberto Exp $
+** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -935,14 +935,19 @@ static void suffixedexp (LexState *ls, expdesc *v) {
static void simpleexp (LexState *ls, expdesc *v) {
- /* simpleexp -> NUMBER | STRING | NIL | TRUE | FALSE | ... |
+ /* simpleexp -> FLT | INT | STRING | NIL | TRUE | FALSE | ... |
constructor | FUNCTION body | suffixedexp */
switch (ls->t.token) {
- case TK_NUMBER: {
- init_exp(v, VKNUM, 0);
+ case TK_FLT: {
+ init_exp(v, VKFLT, 0);
v->u.nval = ls->t.seminfo.r;
break;
}
+ case TK_INT: {
+ init_exp(v, VKINT, 0);
+ v->u.ival = ls->t.seminfo.i;
+ break;
+ }
case TK_STRING: {
codestring(ls, v, ls->t.seminfo.ts);
break;
@@ -1000,6 +1005,7 @@ static BinOpr getbinopr (int op) {
case '-': return OPR_SUB;
case '*': return OPR_MUL;
case '/': return OPR_DIV;
+ case TK_IDIV: return OPR_IDIV;
case '%': return OPR_MOD;
case '^': return OPR_POW;
case TK_CONCAT: return OPR_CONCAT;
@@ -1020,7 +1026,8 @@ 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}, /* `+' `-' `*' `/' `%' */
+ {6, 6}, {6, 6}, /* '+' '-' */
+ {7, 7}, {7, 7}, {7, 7}, {7, 7}, /* '*' '/' '//' '%' */
{10, 9}, {5, 4}, /* ^, .. (right associative) */
{3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
{3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
@@ -1321,7 +1328,7 @@ static void fornum (LexState *ls, TString *varname, int line) {
if (testnext(ls, ','))
exp1(ls); /* optional step */
else { /* default step = 1 */
- luaK_codek(fs, fs->freereg, luaK_numberK(fs, 1));
+ luaK_codek(fs, fs->freereg, luaK_intK(fs, 1));
luaK_reserveregs(fs, 1);
}
forbody(ls, base, line, 1, 1);
diff --git a/src/lparser.h b/src/lparser.h
index 301167d4..147d3367 100644
--- a/src/lparser.h
+++ b/src/lparser.h
@@ -1,5 +1,5 @@
/*
-** $Id: lparser.h,v 1.70 2012/05/08 13:53:33 roberto Exp $
+** $Id: lparser.h,v 1.71 2013/04/16 18:46:28 roberto Exp $
** Lua Parser
** See Copyright Notice in lua.h
*/
@@ -22,7 +22,8 @@ typedef enum {
VTRUE,
VFALSE,
VK, /* info = index of constant in `k' */
- VKNUM, /* nval = numerical value */
+ VKFLT, /* nval = numerical float value */
+ VKINT, /* nval = numerical integer value */
VNONRELOC, /* info = result register */
VLOCAL, /* info = local register */
VUPVAL, /* info = index of upvalue in 'upvalues' */
@@ -46,7 +47,8 @@ typedef struct expdesc {
lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */
} ind;
int info; /* for generic use */
- lua_Number nval; /* for VKNUM */
+ lua_Number nval; /* for VKFLT */
+ lua_Integer ival; /* for VKINT */
} u;
int t; /* patch list of `exit when true' */
int f; /* patch list of `exit when false' */
diff --git a/src/lstring.c b/src/lstring.c
index 8b5af0b2..d9781365 100644
--- a/src/lstring.c
+++ b/src/lstring.c
@@ -1,5 +1,5 @@
/*
-** $Id: lstring.c,v 2.26 2013/01/08 13:50:10 roberto Exp $
+** $Id: lstring.c,v 2.27 2013/06/19 14:27:00 roberto Exp $
** String table (keeps all strings handled by Lua)
** See Copyright Notice in lua.h
*/
@@ -157,7 +157,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) {
if (l <= LUAI_MAXSHORTLEN) /* short string? */
return internshrstr(L, str, l);
else {
- if (l + 1 > (MAX_SIZET - sizeof(TString))/sizeof(char))
+ if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
luaM_toobig(L);
return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL);
}
@@ -174,7 +174,7 @@ TString *luaS_new (lua_State *L, const char *str) {
Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {
Udata *u;
- if (s > MAX_SIZET - sizeof(Udata))
+ if (s > MAX_SIZE - sizeof(Udata))
luaM_toobig(L);
u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;
u->uv.len = s;
diff --git a/src/lstrlib.c b/src/lstrlib.c
index fcc61c9a..28acab83 100644
--- a/src/lstrlib.c
+++ b/src/lstrlib.c
@@ -1,11 +1,12 @@
/*
-** $Id: lstrlib.c,v 1.178 2012/08/14 18:12:34 roberto Exp $
+** $Id: lstrlib.c,v 1.182 2013/06/20 15:06:51 roberto Exp $
** Standard library for string operations and pattern-matching
** See Copyright Notice in lua.h
*/
#include <ctype.h>
+#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -43,20 +44,20 @@ static int str_len (lua_State *L) {
/* 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;
+static lua_Integer posrelat (lua_Integer pos, size_t len) {
+ if (pos >= 0) return pos;
else if (0u - (size_t)pos > len) return 0;
- else return len - ((size_t)-pos) + 1;
+ else return (lua_Integer)len + pos + 1;
}
static int str_sub (lua_State *L) {
size_t l;
const char *s = luaL_checklstring(L, 1, &l);
- size_t start = posrelat(luaL_checkinteger(L, 2), l);
- size_t end = posrelat(luaL_optinteger(L, 3, -1), l);
+ lua_Integer start = posrelat(luaL_checkinteger(L, 2), l);
+ lua_Integer end = posrelat(luaL_optinteger(L, 3, -1), l);
if (start < 1) start = 1;
- if (end > l) end = l;
+ if (end > (lua_Integer)l) end = l;
if (start <= end)
lua_pushlstring(L, s + start - 1, end - start + 1);
else lua_pushliteral(L, "");
@@ -102,13 +103,17 @@ static int str_upper (lua_State *L) {
}
-/* reasonable limit to avoid arithmetic overflow */
-#define MAXSIZE ((~(size_t)0) >> 1)
+/* reasonable limit to avoid arithmetic overflow and strings too big */
+#if INT_MAX / 2 <= 0x10000000
+#define MAXSIZE ((size_t)(INT_MAX / 2))
+#else
+#define MAXSIZE ((size_t)0x10000000)
+#endif
static int str_rep (lua_State *L) {
size_t l, lsep;
const char *s = luaL_checklstring(L, 1, &l);
- int n = luaL_checkint(L, 2);
+ lua_Integer n = luaL_checkinteger(L, 2);
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? */
@@ -133,14 +138,14 @@ 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);
- size_t posi = posrelat(luaL_optinteger(L, 2, 1), l);
- size_t pose = posrelat(luaL_optinteger(L, 3, posi), l);
+ lua_Integer posi = posrelat(luaL_optinteger(L, 2, 1), l);
+ lua_Integer pose = posrelat(luaL_optinteger(L, 3, posi), l);
int n, i;
if (posi < 1) posi = 1;
- if (pose > l) pose = l;
+ if (pose > (lua_Integer)l) pose = l;
if (posi > pose) return 0; /* empty interval; return no values */
n = (int)(pose - posi + 1);
- if (posi + n <= pose) /* (size_t -> int) overflow? */
+ if (posi + n <= pose) /* arithmetic overflow? */
return luaL_error(L, "string slice too long");
luaL_checkstack(L, n, "string slice too long");
for (i=0; i<n; i++)
@@ -155,7 +160,7 @@ static int str_char (lua_State *L) {
luaL_Buffer b;
char *p = luaL_buffinitsize(L, &b, n);
for (i=1; i<=n; i++) {
- int c = luaL_checkint(L, i);
+ lua_Integer c = luaL_checkinteger(L, i);
luaL_argcheck(L, uchar(c) == c, i, "value out of range");
p[i - 1] = uchar(c);
}
@@ -164,9 +169,9 @@ static int str_char (lua_State *L) {
}
-static int writer (lua_State *L, const void* b, size_t size, void* B) {
+static int writer (lua_State *L, const void *b, size_t size, void *B) {
(void)L;
- luaL_addlstring((luaL_Buffer*) B, (const char *)b, size);
+ luaL_addlstring((luaL_Buffer *) B, (const char *)b, size);
return 0;
}
@@ -578,9 +583,9 @@ static int str_find_aux (lua_State *L, int find) {
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);
+ lua_Integer init = posrelat(luaL_optinteger(L, 3, 1), ls);
if (init < 1) init = 1;
- else if (init > ls + 1) { /* start after string's end? */
+ else if (init > (lua_Integer)ls + 1) { /* start after string's end? */
lua_pushnil(L); /* cannot find anything */
return 1;
}
@@ -786,48 +791,17 @@ static int str_gsub (lua_State *L) {
** =======================================================
*/
-/*
-** 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 /* } */
-
-
-/*
-** 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 */
#define FLAGS "-+ #0"
+
/*
-** maximum size of each format specification (such as '%-099.99d')
-** (+10 accounts for %99.99x plus margin of error)
+** maximum size of each format specification (such as "%-099.99d")
+** (+2 for length modifiers; +10 accounts for %99.99x plus margin of error)
*/
-#define MAX_FORMAT (sizeof(FLAGS) + sizeof(LUA_INTFRMLEN) + 10)
+#define MAX_FORMAT (sizeof(FLAGS) + 2 + 10)
static void addquoted (lua_State *L, luaL_Buffer *b, int arg) {
@@ -914,24 +888,11 @@ static int str_format (lua_State *L) {
nb = sprintf(buff, form, luaL_checkint(L, arg));
break;
}
- case 'd': case 'i': {
- lua_Number n = luaL_checknumber(L, arg);
- LUA_INTFRM_T ni = (LUA_INTFRM_T)n;
- lua_Number diff = n - (lua_Number)ni;
- luaL_argcheck(L, -1 < diff && diff < 1, arg,
- "not a number in proper range");
- addlenmod(form, LUA_INTFRMLEN);
- nb = sprintf(buff, form, ni);
- break;
- }
+ case 'd': case 'i':
case 'o': case 'u': case 'x': case 'X': {
- lua_Number n = luaL_checknumber(L, arg);
- unsigned LUA_INTFRM_T ni = (unsigned LUA_INTFRM_T)n;
- lua_Number diff = n - (lua_Number)ni;
- luaL_argcheck(L, -1 < diff && diff < 1, arg,
- "not a non-negative number in proper range");
- addlenmod(form, LUA_INTFRMLEN);
- nb = sprintf(buff, form, ni);
+ lua_Integer n = luaL_checkinteger(L, arg);
+ addlenmod(form, LUA_INTEGER_FRMLEN);
+ nb = sprintf(buff, form, n);
break;
}
case 'e': case 'E': case 'f':
@@ -939,8 +900,8 @@ static int str_format (lua_State *L) {
case 'a': case 'A':
#endif
case 'g': case 'G': {
- addlenmod(form, LUA_FLTFRMLEN);
- nb = sprintf(buff, form, (LUA_FLTFRM_T)luaL_checknumber(L, arg));
+ addlenmod(form, LUA_NUMBER_FRMLEN);
+ nb = sprintf(buff, form, luaL_checknumber(L, arg));
break;
}
case 'q': {
diff --git a/src/ltable.c b/src/ltable.c
index 420391fc..4b39a8de 100644
--- a/src/ltable.c
+++ b/src/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.72 2012/09/11 19:37:16 roberto Exp $
+** $Id: ltable.c,v 2.78 2013/06/20 15:02:49 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -18,6 +18,8 @@
** Hence even when the load factor reaches 100%, performance remains good.
*/
+#include <float.h>
+#include <math.h>
#include <string.h>
#define ltable_c
@@ -52,6 +54,7 @@
#define hashstr(t,str) hashpow2(t, (str)->tsv.hash)
#define hashboolean(t,p) hashpow2(t, p)
+#define hashint(t,i) hashpow2(t, i)
/*
@@ -64,6 +67,12 @@
#define hashpointer(t,p) hashmod(t, IntPoint(p))
+/* checks whether a float has a value representable as a lua_Integer
+ (and does the conversion if so) */
+#define numisinteger(x,i) \
+ (((x) == l_floor(x)) && luaV_numtointeger(x, i))
+
+
#define dummynode (&dummynode_)
#define isdummy(n) ((n) == dummynode)
@@ -75,11 +84,12 @@ static const Node dummynode_ = {
/*
-** hash for lua_Numbers
+** hash for floating-point numbers
*/
-static Node *hashnum (const Table *t, lua_Number n) {
+static Node *hashfloat (const Table *t, lua_Number n) {
int i;
- luai_hashnum(i, n);
+ n = l_mathop(frexp)(n, &i) * cast_num(INT_MAX - DBL_MAX_EXP);
+ i += cast_int(n);
if (i < 0) {
if (cast(unsigned int, i) == 0u - i) /* use unsigned to avoid overflows */
i = 0; /* handle INT_MIN */
@@ -96,8 +106,12 @@ static Node *hashnum (const Table *t, lua_Number n) {
*/
static Node *mainposition (const Table *t, const TValue *key) {
switch (ttype(key)) {
- case LUA_TNUMBER:
- return hashnum(t, nvalue(key));
+ case LUA_TNUMINT:
+ return hashint(t, ivalue(key));
+ case LUA_TNUMFLT:
+ return hashfloat(t, fltvalue(key));
+ case LUA_TSHRSTR:
+ return hashstr(t, rawtsvalue(key));
case LUA_TLNGSTR: {
TString *s = rawtsvalue(key);
if (s->tsv.extra == 0) { /* no hash? */
@@ -106,8 +120,6 @@ static Node *mainposition (const Table *t, const TValue *key) {
}
return hashstr(t, rawtsvalue(key));
}
- case LUA_TSHRSTR:
- return hashstr(t, rawtsvalue(key));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
@@ -125,12 +137,10 @@ static Node *mainposition (const Table *t, const TValue *key) {
** the array part of the table, -1 otherwise.
*/
static int arrayindex (const TValue *key) {
- if (ttisnumber(key)) {
- lua_Number n = nvalue(key);
- int k;
- lua_number2int(k, n);
- if (luai_numeq(cast_num(k), n))
- return k;
+ if (ttisinteger(key)) {
+ lua_Integer k = ivalue(key);
+ if (0 < k && k <= MAXASIZE) /* is `key' an appropriate array index? */
+ return cast_int(k);
}
return -1; /* `key' did not match some condition */
}
@@ -170,7 +180,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
int i = findindex(L, t, key); /* find original element */
for (i++; i < t->sizearray; i++) { /* try first array part */
if (!ttisnil(&t->array[i])) { /* a non-nil value? */
- setnvalue(key, cast_num(i+1));
+ setivalue(key, i + 1);
setobj2s(L, key+1, &t->array[i]);
return 1;
}
@@ -217,7 +227,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? */
+ if (k > 0) { /* is `key' an appropriate array index? */
nums[luaO_ceillog2(k)]++; /* count as such */
return 1;
}
@@ -404,9 +414,18 @@ static Node *getfreepos (Table *t) {
*/
TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
Node *mp;
+ TValue aux;
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");
+ else if (ttisfloat(key)) {
+ lua_Number n = fltvalue(key);
+ lua_Integer k;
+ if (luai_numisnan(L, n))
+ luaG_runerror(L, "table index is NaN");
+ if (numisinteger(n, &k)) { /* index is int? */
+ setivalue(&aux, k);
+ key = &aux; /* insert it as an integer */
+ }
+ }
mp = mainposition(t, key);
if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
Node *othern;
@@ -443,15 +462,14 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
/*
** search function for integers
*/
-const TValue *luaH_getint (Table *t, int key) {
+const TValue *luaH_getint (Table *t, lua_Integer key) {
/* (1 <= key && key <= t->sizearray) */
- if (cast(unsigned int, key-1) < cast(unsigned int, t->sizearray))
- return &t->array[key-1];
+ if (cast_unsigned(key - 1) < cast_unsigned(t->sizearray))
+ return &t->array[key - 1];
else {
- lua_Number nk = cast_num(key);
- Node *n = hashnum(t, nk);
+ Node *n = hashint(t, key);
do { /* check whether `key' is somewhere in the chain */
- if (ttisnumber(gkey(n)) && luai_numeq(nvalue(gkey(n)), nk))
+ if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
return gval(n); /* that's it */
else n = gnext(n);
} while (n);
@@ -481,12 +499,11 @@ const TValue *luaH_getstr (Table *t, TString *key) {
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
case LUA_TSHRSTR: return luaH_getstr(t, rawtsvalue(key));
+ case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
case LUA_TNIL: return luaO_nilobject;
- case LUA_TNUMBER: {
- int k;
- lua_Number n = nvalue(key);
- lua_number2int(k, n);
- if (luai_numeq(cast_num(k), n)) /* index is int? */
+ case LUA_TNUMFLT: {
+ lua_Integer k;
+ if (numisinteger(fltvalue(key), &k)) /* index is int? */
return luaH_getint(t, k); /* use specialized version */
/* else go through */
}
@@ -515,14 +532,14 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
}
-void luaH_setint (lua_State *L, Table *t, int key, TValue *value) {
+void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
const TValue *p = luaH_getint(t, key);
TValue *cell;
if (p != luaO_nilobject)
cell = cast(TValue *, p);
else {
TValue k;
- setnvalue(&k, cast_num(key));
+ setivalue(&k, key);
cell = luaH_newkey(L, t, &k);
}
setobj2t(L, cell, value);
@@ -535,13 +552,13 @@ static int unbound_search (Table *t, unsigned int j) {
/* find `i' and `j' such that i is present and j is not */
while (!ttisnil(luaH_getint(t, j))) {
i = j;
- j *= 2;
- if (j > cast(unsigned int, MAX_INT)) { /* overflow? */
+ if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */
/* table was built with bad purposes: resort to linear search */
i = 1;
while (!ttisnil(luaH_getint(t, i))) i++;
return i - 1;
}
+ j *= 2;
}
/* now do a binary search between them */
while (j - i > 1) {
diff --git a/src/ltable.h b/src/ltable.h
index 2f6f5c2d..5a65b52e 100644
--- a/src/ltable.h
+++ b/src/ltable.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.h,v 2.16 2011/08/17 20:26:47 roberto Exp $
+** $Id: ltable.h,v 2.17 2013/04/26 15:39:25 roberto Exp $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -18,8 +18,9 @@
#define invalidateTMcache(t) ((t)->flags = 0)
-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_getint (Table *t, lua_Integer key);
+LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
+ TValue *value);
LUAI_FUNC const TValue *luaH_getstr (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);
diff --git a/src/ltm.c b/src/ltm.c
index e70006dd..3d1126a1 100644
--- a/src/ltm.c
+++ b/src/ltm.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.c,v 2.14 2011/06/02 19:31:40 roberto Exp $
+** $Id: ltm.c,v 2.20 2013/05/06 17:19:11 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -12,11 +12,14 @@
#include "lua.h"
+#include "ldebug.h"
+#include "ldo.h"
#include "lobject.h"
#include "lstate.h"
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
+#include "lvm.h"
static const char udatatypename[] = "userdata";
@@ -33,7 +36,7 @@ void luaT_init (lua_State *L) {
static const char *const luaT_eventname[] = { /* ORDER TM */
"__index", "__newindex",
"__gc", "__mode", "__len", "__eq",
- "__add", "__sub", "__mul", "__div", "__mod",
+ "__add", "__sub", "__mul", "__div", "__idiv", "__mod",
"__pow", "__unm", "__lt", "__le",
"__concat", "__call"
};
@@ -62,7 +65,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 (ttypenv(o)) {
+ switch (ttnov(o)) {
case LUA_TTABLE:
mt = hvalue(o)->metatable;
break;
@@ -70,8 +73,71 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
mt = uvalue(o)->metatable;
break;
default:
- mt = G(L)->mt[ttypenv(o)];
+ mt = G(L)->mt[ttnov(o)];
}
return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
}
+
+void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
+ 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 */
+ /* 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);
+ }
+}
+
+
+int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
+ StkId res, TMS event) {
+ const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
+ if (ttisnil(tm))
+ tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
+ if (ttisnil(tm)) return 0;
+ luaT_callTM(L, tm, p1, p2, res, 1);
+ return 1;
+}
+
+
+void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
+ StkId res, TMS event) {
+ if (!luaT_callbinTM(L, p1, p2, res, event)) {
+ if (event == TM_CONCAT)
+ luaG_concaterror(L, p1, p2);
+ else if (event == TM_IDIV && ttisnumber(p1) && ttisnumber(p2))
+ luaG_tointerror(L, p1, p2);
+ else
+ luaG_aritherror(L, p1, p2);
+ }
+}
+
+
+const TValue *luaT_getequalTM (lua_State *L, Table *mt1, Table *mt2) {
+ const TValue *tm1 = fasttm(L, mt1, TM_EQ);
+ const TValue *tm2;
+ if (tm1 == NULL) return NULL; /* no metamethod */
+ if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
+ tm2 = fasttm(L, mt2, TM_EQ);
+ if (tm2 == NULL) return NULL; /* no metamethod */
+ if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */
+ return tm1;
+ return NULL;
+}
+
+
+int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
+ TMS event) {
+ if (!luaT_callbinTM(L, p1, p2, L->top, event))
+ return -1; /* no metamethod */
+ else
+ return !l_isfalse(L->top);
+}
+
diff --git a/src/ltm.h b/src/ltm.h
index 89bdc19a..206823ef 100644
--- a/src/ltm.h
+++ b/src/ltm.h
@@ -1,5 +1,5 @@
/*
-** $Id: ltm.h,v 2.11 2011/02/28 17:32:10 roberto Exp $
+** $Id: ltm.h,v 2.16 2013/04/29 16:56:50 roberto Exp $
** Tag methods
** See Copyright Notice in lua.h
*/
@@ -26,6 +26,7 @@ typedef enum {
TM_SUB,
TM_MUL,
TM_DIV,
+ TM_IDIV,
TM_MOD,
TM_POW,
TM_UNM,
@@ -44,7 +45,7 @@ typedef enum {
#define fasttm(l,et,e) gfasttm(G(l), et, e)
#define ttypename(x) luaT_typenames_[(x) + 1]
-#define objtypename(x) ttypename(ttypenv(x))
+#define objtypename(x) ttypename(ttnov(x))
LUAI_DDEC const char *const luaT_typenames_[LUA_TOTALTAGS];
@@ -54,4 +55,16 @@ LUAI_FUNC const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o,
TMS event);
LUAI_FUNC void luaT_init (lua_State *L);
+LUAI_FUNC void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
+ const TValue *p2, TValue *p3, int hasres);
+LUAI_FUNC int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
+ StkId res, TMS event);
+LUAI_FUNC void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
+ StkId res, TMS event);
+LUAI_FUNC const TValue *luaT_getequalTM (lua_State *L, Table *mt1, Table *mt2);
+LUAI_FUNC int luaT_callorderTM (lua_State *L, const TValue *p1,
+ const TValue *p2, TMS event);
+
+
+
#endif
diff --git a/src/lua.h b/src/lua.h
index eb0482b8..4fef6fee 100644
--- a/src/lua.h
+++ b/src/lua.h
@@ -1,5 +1,5 @@
/*
-** $Id: lua.h,v 1.285 2013/03/15 13:04:22 roberto Exp $
+** $Id: lua.h,v 1.292 2013/07/05 14:29:51 roberto Exp $
** Lua - A Scripting Language
** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
** See Copyright Notice at the end of this file
@@ -17,9 +17,9 @@
#define LUA_VERSION_MAJOR "5"
-#define LUA_VERSION_MINOR "2"
-#define LUA_VERSION_NUM 502
-#define LUA_VERSION_RELEASE "2"
+#define LUA_VERSION_MINOR "3"
+#define LUA_VERSION_NUM 503
+#define LUA_VERSION_RELEASE "0 (work1)"
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
@@ -61,7 +61,7 @@ typedef int (*lua_CFunction) (lua_State *L);
*/
typedef const char * (*lua_Reader) (lua_State *L, void *ud, size_t *sz);
-typedef int (*lua_Writer) (lua_State *L, const void* p, size_t sz, void* ud);
+typedef int (*lua_Writer) (lua_State *L, const void *p, size_t sz, void *ud);
/*
@@ -161,6 +161,7 @@ LUA_API void (lua_xmove) (lua_State *from, lua_State *to, int n);
LUA_API int (lua_isnumber) (lua_State *L, int idx);
LUA_API int (lua_isstring) (lua_State *L, int idx);
LUA_API int (lua_iscfunction) (lua_State *L, int idx);
+LUA_API int (lua_isinteger) (lua_State *L, int idx);
LUA_API int (lua_isuserdata) (lua_State *L, int idx);
LUA_API int (lua_type) (lua_State *L, int idx);
LUA_API const char *(lua_typename) (lua_State *L, int tp);
@@ -185,9 +186,10 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx);
#define LUA_OPSUB 1
#define LUA_OPMUL 2
#define LUA_OPDIV 3
-#define LUA_OPMOD 4
-#define LUA_OPPOW 5
-#define LUA_OPUNM 6
+#define LUA_OPIDIV 4
+#define LUA_OPMOD 5
+#define LUA_OPPOW 6
+#define LUA_OPUNM 7
LUA_API void (lua_arith) (lua_State *L, int op);
@@ -224,7 +226,7 @@ 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_rawgeti) (lua_State *L, int idx, lua_Integer 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);
@@ -239,7 +241,7 @@ 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_rawseti) (lua_State *L, int idx, lua_Integer 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 void (lua_setuservalue) (lua_State *L, int idx);
@@ -305,6 +307,8 @@ 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 int (lua_strtonum) (lua_State *L, const char *s, size_t len);
+
LUA_API lua_Alloc (lua_getallocf) (lua_State *L, void **ud);
LUA_API void (lua_setallocf) (lua_State *L, lua_Alloc f, void *ud);
diff --git a/src/luac.c b/src/luac.c
index 5081836d..43c3d0d6 100644
--- a/src/luac.c
+++ b/src/luac.c
@@ -202,8 +202,10 @@ int main(int argc, char* argv[])
return EXIT_SUCCESS;
}
+#define nvalue(x) 0
+#define ttypenv(x) ttnov(x)
/*
-** $Id: print.c,v 1.68 2011/09/30 10:21:20 lhf Exp $
+** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $
** print bytecodes
** See Copyright Notice in lua.h
*/
@@ -251,7 +253,7 @@ static void PrintString(const TString* ts)
static void PrintConstant(const Proto* f, int i)
{
const TValue* o=&f->k[i];
- switch (ttype(o))
+ switch (ttypenv(o))
{
case LUA_TNIL:
printf("nil");
diff --git a/src/luaconf.h b/src/luaconf.h
index df802c95..71d02561 100644
--- a/src/luaconf.h
+++ b/src/luaconf.h
@@ -1,5 +1,5 @@
/*
-** $Id: luaconf.h,v 1.176 2013/03/16 21:10:18 roberto Exp $
+** $Id: luaconf.h,v 1.185 2013/06/25 19:04:40 roberto Exp $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@@ -376,64 +376,112 @@
/*
** {==================================================================
-@@ LUA_NUMBER is the type of numbers in Lua.
-** CHANGE the following definitions only if you want to build Lua
-** with a number type different from double. You may also need to
-** change lua_number2int & lua_number2integer.
+** The following definitions set the numeric types for Lua.
+** Lua should work fine with 32-bit or 64-bit integers mixed with
+** 32-bit or 64-bit floats. The usual configurations are 64-bit
+** integers and floats (the default) and 32-bit integers and floats.
** ===================================================================
*/
-#define LUA_NUMBER_DOUBLE
-#define LUA_NUMBER double
+/*
+@@ LUA_INTSIZE defines size for Lua integer: 1=int, 2=long, 3=long long
+@@ LUA_FLOATSIZE defines size for Lua float: 1=float, 2=double, 3=long double
+** Default is long long + double
+*/
+#define LUA_INTSIZE 3
+#define LUA_FLOATSIZE 2
+
/*
+@@ LUA_NUMBER is the floating-point type used by Lua.
+**
@@ LUAI_UACNUMBER is the result of an 'usual argument conversion'
-@* over a number.
+@* over a floating number.
+**
+@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
+@@ LUA_NUMBER_SCAN is the format for reading floats.
+@@ LUA_NUMBER_FMT is the format for writing floats.
+@@ lua_number2str converts a floats to a string.
+**
+@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
+**
+@@ lua_str2number converts a decimal numeric string to a number.
*/
+
+#if LUA_FLOATSIZE == 1 /* { single float */
+
+#define LUA_NUMBER float
+
#define LUAI_UACNUMBER double
+#define LUA_NUMBER_FRMLEN ""
+#define LUA_NUMBER_SCAN "%f"
+#define LUA_NUMBER_FMT "%.7g"
-/*
-@@ LUA_NUMBER_SCAN is the format for reading numbers.
-@@ 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.
-*/
+#define l_mathop(op) op##f
+
+#define lua_str2number(s,p) strtof((s), (p))
+
+
+#elif LUA_FLOATSIZE == 3 /* }{ long double */
+
+#define LUA_NUMBER long double
+
+#define LUAI_UACNUMBER long double
+
+#define LUA_NUMBER_FRMLEN "L"
+#define LUA_NUMBER_SCAN "%Lf"
+#define LUA_NUMBER_FMT "%.19Lg"
+
+#define l_mathop(op) op##l
+
+#define lua_str2number(s,p) strtold((s), (p))
+
+#else /* }{ default: double */
+
+#define LUA_NUMBER double
+
+#define LUAI_UACNUMBER double
+
+#define LUA_NUMBER_FRMLEN ""
#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 */
+#define l_mathop(op) op
-/*
-@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
-*/
-#define l_mathop(x) (x)
+#define lua_str2number(s,p) strtod((s), (p))
+#endif /* } */
-/*
-@@ lua_str2number converts a decimal numeric string to a number.
-@@ lua_strx2number converts an hexadecimal numeric string to a number.
-** In C99, 'strtod' does 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))
+#if defined(LUA_ANSI)
+/* C89 does not support 'opf' variants for math functions */
+#undef l_mathop
+#define l_mathop(op) (lua_Number)op
+#endif
+
+
+#if defined(LUA_ANSI) || defined(_WIN32)
+/* C89 and Windows do not support 'strtof'... */
+#undef lua_str2number
+#define lua_str2number(s,p) ((lua_Number)strtod((s), (p)))
#endif
+#define l_floor(x) (l_mathop(floor)(x))
+
+#define lua_number2str(s,n) sprintf((s), LUA_NUMBER_FMT, (n))
+
+
/*
@@ The luai_num* macros define the primitive operations over numbers.
+@* They should work for any size of floating numbers.
*/
/* the following operations need the math library */
#if defined(lobject_c) || defined(lvm_c)
#include <math.h>
-#define luai_nummod(L,a,b) ((a) - l_mathop(floor)((a)/(b))*(b))
+#define luai_nummod(L,a,b) ((a) - l_floor((a)/(b))*(b))
#define luai_numpow(L,a,b) (l_mathop(pow)(a,b))
#endif
@@ -453,85 +501,39 @@
/*
-@@ 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
-
-/*
-@@ 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
-
-
-
-/*
-** Some tricks with doubles
-*/
-
-#if defined(LUA_NUMBER_DOUBLE) && !defined(LUA_ANSI) /* { */
-/*
-** The next definitions activate some tricks to speed up the
-** conversion from doubles to integer types, mainly to LUA_UNSIGNED.
+@@ LUA_INTEGER is the integer type used by Lua.
**
-@@ LUA_MSASMTRICK uses Microsoft assembler to avoid clashes with a
-** DirectX idiosyncrasy.
+@@ LUA_UNSIGNED is the unsigned version of LUA_INTEGER.
**
-@@ LUA_IEEE754TRICK uses a trick that should work on any machine
-** using IEEE754 with a 32-bit integer type.
-**
-@@ LUA_IEEELL extends the trick to LUA_INTEGER; should only be
-** defined when LUA_INTEGER is a 32-bit integer.
-**
-@@ 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 for LUA_IEEE754TRICK (but not for LUA_NANTRICK).
-**
-@@ LUA_NANTRICK 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).
+@@ LUA_INTEGER_FRMLEN is the length modifier for reading/writing integers.
+@@ LUA_INTEGER_SCAN is the format for reading integers.
+@@ LUA_INTEGER_FMT is the format for writing integers.
+@@ lua_integer2str converts an integer to a string.
*/
-/* Microsoft compiler on a Pentium (32 bit) ? */
-#if defined(LUA_WIN) && defined(_MSC_VER) && defined(_M_IX86) /* { */
-
-#define LUA_MSASMTRICK
-#define LUA_IEEEENDIAN 0
-#define LUA_NANTRICK
+#if LUA_INTSIZE == 1 /* { int */
+#define LUA_INTEGER int
+#define LUA_INTEGER_FRMLEN ""
-/* pentium 32 bits? */
-#elif defined(__i386__) || defined(__i386) || defined(__X86__) /* }{ */
+#elif LUA_INTSIZE == 2 /* }{ long */
-#define LUA_IEEE754TRICK
-#define LUA_IEEELL
-#define LUA_IEEEENDIAN 0
-#define LUA_NANTRICK
+#define LUA_INTEGER long
+#define LUA_INTEGER_FRMLEN "l"
-/* pentium 64 bits? */
-#elif defined(__x86_64) /* }{ */
+#else /* }{ default: long long */
-#define LUA_IEEE754TRICK
-#define LUA_IEEEENDIAN 0
+#define LUA_INTEGER long long
+#define LUA_INTEGER_FRMLEN "ll"
-#elif defined(__POWERPC__) || defined(__ppc__) /* }{ */
+#endif /* } */
-#define LUA_IEEE754TRICK
-#define LUA_IEEEENDIAN 1
-#else /* }{ */
+#define LUA_INTEGER_SCAN "%" LUA_INTEGER_FRMLEN "d"
+#define LUA_INTEGER_FMT "%" LUA_INTEGER_FRMLEN "d"
+#define lua_integer2str(s,n) sprintf((s), LUA_INTEGER_FMT, (n))
-/* assume IEEE754 and a 32-bit integer type */
-#define LUA_IEEE754TRICK
-
-#endif /* } */
-
-#endif /* } */
+#define LUA_UNSIGNED unsigned LUA_INTEGER
/* }================================================================== */
@@ -547,5 +549,7 @@
+
+
#endif
diff --git a/src/lundump.c b/src/lundump.c
index 54de011a..38b04e42 100644
--- a/src/lundump.c
+++ b/src/lundump.c
@@ -1,5 +1,5 @@
/*
-** $Id: lundump.c,v 2.22 2012/05/08 13:53:33 roberto Exp $
+** $Id: lundump.c,v 2.23 2013/04/26 18:48:35 roberto Exp $
** load precompiled Lua chunks
** See Copyright Notice in lua.h
*/
@@ -69,6 +69,13 @@ static lua_Number LoadNumber(LoadState* S)
return x;
}
+static lua_Integer LoadInteger(LoadState* S)
+{
+ lua_Integer x;
+ LoadVar(S,x);
+ return x;
+}
+
static TString* LoadString(LoadState* S)
{
size_t size;
@@ -112,10 +119,13 @@ static void LoadConstants(LoadState* S, Proto* f)
case LUA_TBOOLEAN:
setbvalue(o,LoadChar(S));
break;
- case LUA_TNUMBER:
+ case LUA_TNUMFLT:
setnvalue(o,LoadNumber(S));
break;
- case LUA_TSTRING:
+ case LUA_TNUMINT:
+ setivalue(o,LoadInteger(S));
+ break;
+ case LUA_TSHRSTR: case LUA_TLNGSTR:
setsvalue2n(S->L,o,LoadString(S));
break;
default: lua_assert(0);
diff --git a/src/lvm.c b/src/lvm.c
index 657d5c45..0a41482c 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.c,v 2.155 2013/03/16 21:10:18 roberto Exp $
+** $Id: lvm.c,v 2.175 2013/06/20 15:02:49 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -32,15 +32,18 @@
#define MAXTAGLOOP 100
-const TValue *luaV_tonumber (const TValue *obj, TValue *n) {
- lua_Number num;
- if (ttisnumber(obj)) return obj;
- if (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, &num)) {
- setnvalue(n, num);
- return n;
+/* maximum length of the conversion of a number to a string */
+#define MAXNUMBER2STR 50
+
+
+int luaV_tonumber_ (const TValue *obj, lua_Number *n) {
+ lua_assert(!ttisfloat(obj));
+ if (ttisinteger(obj)) {
+ *n = cast_num(ivalue(obj));
+ return 1;
}
else
- return NULL;
+ return (ttisstring(obj) && luaO_str2d(svalue(obj), tsvalue(obj)->len, n));
}
@@ -48,62 +51,51 @@ int luaV_tostring (lua_State *L, StkId obj) {
if (!ttisnumber(obj))
return 0;
else {
- char s[LUAI_MAXNUMBER2STR];
- lua_Number n = nvalue(obj);
- int l = lua_number2str(s, n);
- setsvalue2s(L, obj, luaS_newlstr(L, s, l));
+ char buff[MAXNUMBER2STR];
+ size_t len;
+ if (ttisinteger(obj))
+ len = lua_integer2str(buff, ivalue(obj));
+ else {
+ len = lua_number2str(buff, fltvalue(obj));
+ if (strspn(buff, "-0123456789") == len) { /* look like an integer? */
+ buff[len++] = '.'; /* add a '.0' */
+ buff[len++] = '0';
+ buff[len] = '\0';
+ }
+ }
+ setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
return 1;
}
}
-static void traceexec (lua_State *L) {
- CallInfo *ci = L->ci;
- lu_byte mask = L->hookmask;
- int counthook = ((mask & LUA_MASKCOUNT) && L->hookcount == 0);
- if (counthook)
- resethookcount(L); /* reset count */
- if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
- ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
- return; /* do not call hook again (VM yielded, so it did not move) */
- }
- if (counthook)
- luaD_hook(L, LUA_HOOKCOUNT, -1); /* call count hook */
- if (mask & LUA_MASKLINE) {
- 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); /* call line hook */
- }
- L->oldpc = ci->u.l.savedpc;
- if (L->status == LUA_YIELD) { /* did hook yield? */
- if (counthook)
- L->hookcount = 1; /* undo decrement to zero */
- ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
- ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
- ci->func = L->top - 1; /* protect stack below results */
- luaD_throw(L, LUA_YIELD);
+/*
+** Check whether a float number is within the range of a lua_Integer.
+** (The comparisons are tricky because of rounding, which can or
+** not occur depending on the relative sizes of floats and integers.)
+** This function is called only when 'n' has an integer value.
+*/
+int luaV_numtointeger (lua_Number n, lua_Integer *p) {
+ if (cast_num(MIN_INTEGER) <= n && n < (MAX_INTEGER + cast_num(1))) {
+ *p = cast_integer(n);
+ lua_assert(cast_num(*p) == n);
+ return 1;
}
+ return 0; /* number is outside integer limits */
}
-static void callTM (lua_State *L, const TValue *f, const TValue *p1,
- 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 */
- /* 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);
+/*
+** try to convert a non-integer value to an integer
+*/
+int luaV_tointeger_ (const TValue *obj, lua_Integer *p) {
+ lua_Number n;
+ lua_assert(!ttisinteger(obj));
+ if (tonumber(obj, &n)) {
+ n = l_floor(n);
+ return luaV_numtointeger(n, p);
}
+ else return 0;
}
@@ -124,7 +116,7 @@ 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)) {
- callTM(L, tm, t, key, val, 1);
+ luaT_callTM(L, tm, t, key, val, 1);
return;
}
t = tm; /* else repeat with 'tm' */
@@ -163,7 +155,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
luaG_typeerror(L, t, "index");
/* there is a metamethod */
if (ttisfunction(tm)) {
- callTM(L, tm, t, key, val, 0);
+ luaT_callTM(L, tm, t, key, val, 0);
return;
}
t = tm; /* else repeat with 'tm' */
@@ -172,40 +164,6 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
}
-static int call_binTM (lua_State *L, const TValue *p1, const TValue *p2,
- StkId res, TMS event) {
- const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
- if (ttisnil(tm))
- tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
- if (ttisnil(tm)) return 0;
- callTM(L, tm, p1, p2, res, 1);
- return 1;
-}
-
-
-static const TValue *get_equalTM (lua_State *L, Table *mt1, Table *mt2,
- TMS event) {
- const TValue *tm1 = fasttm(L, mt1, event);
- const TValue *tm2;
- if (tm1 == NULL) return NULL; /* no metamethod */
- if (mt1 == mt2) return tm1; /* same metatables => same metamethods */
- tm2 = fasttm(L, mt2, event);
- if (tm2 == NULL) return NULL; /* no metamethod */
- if (luaV_rawequalobj(tm1, tm2)) /* same metamethods? */
- return tm1;
- return NULL;
-}
-
-
-static int call_orderTM (lua_State *L, const TValue *p1, const TValue *p2,
- TMS event) {
- if (!call_binTM(L, p1, p2, L->top, event))
- return -1; /* no metamethod */
- else
- return !l_isfalse(L->top);
-}
-
-
static int l_strcmp (const TString *ls, const TString *rs) {
const char *l = getstr(ls);
size_t ll = ls->tsv.len;
@@ -230,11 +188,14 @@ 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 (ttisnumber(l) && ttisnumber(r))
- return luai_numlt(L, nvalue(l), nvalue(r));
+ lua_Number nl, nr;
+ if (ttisinteger(l) && ttisinteger(r))
+ return (ivalue(l) < ivalue(r));
+ else if (tonumber(l, &nl) && tonumber(r, &nr))
+ return luai_numlt(L, nl, nr);
else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
- else if ((res = call_orderTM(L, l, r, TM_LT)) < 0)
+ else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)
luaG_ordererror(L, l, r);
return res;
}
@@ -242,13 +203,16 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) {
int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
int res;
- if (ttisnumber(l) && ttisnumber(r))
- return luai_numle(L, nvalue(l), nvalue(r));
+ lua_Number nl, nr;
+ if (ttisinteger(l) && ttisinteger(r))
+ return (ivalue(l) <= ivalue(r));
+ else if (tonumber(l, &nl) && tonumber(r, &nr))
+ return luai_numle(L, nl, nr);
else if (ttisstring(l) && ttisstring(r))
return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
- else if ((res = call_orderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
+ else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
return res;
- else if ((res = call_orderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
+ else if ((res = luaT_callorderTM(L, r, l, TM_LT)) < 0) /* else try `lt' */
luaG_ordererror(L, l, r);
return !res;
}
@@ -257,12 +221,23 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) {
/*
** equality of Lua values. L == NULL means raw equality (no metamethods)
*/
-int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
+int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) {
const TValue *tm;
- lua_assert(ttisequal(t1, t2));
+ if (ttype(t1) != ttype(t2)) {
+ if (ttnov(t1) != ttnov(t2) || ttnov(t1) != LUA_TNUMBER)
+ return 0; /* only numbers can be equal with different variants */
+ else { /* two numbers with different variants */
+ lua_Number n1, n2;
+ lua_assert(ttisnumber(t1) && ttisnumber(t2));
+ (void)tonumber(t1, &n1); (void)tonumber(t2, &n2);
+ return luai_numeq(n1, n2);
+ }
+ }
+ /* values have same type and same variant */
switch (ttype(t1)) {
case LUA_TNIL: return 1;
- case LUA_TNUMBER: return luai_numeq(nvalue(t1), nvalue(t2));
+ case LUA_TNUMINT: return (ivalue(t1) == ivalue(t2));
+ case LUA_TNUMFLT: return luai_numeq(fltvalue(t1), fltvalue(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);
@@ -271,21 +246,20 @@ int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2) {
case LUA_TUSERDATA: {
if (uvalue(t1) == uvalue(t2)) return 1;
else if (L == NULL) return 0;
- tm = get_equalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable, TM_EQ);
+ tm = luaT_getequalTM(L, uvalue(t1)->metatable, uvalue(t2)->metatable);
break; /* will try TM */
}
case LUA_TTABLE: {
if (hvalue(t1) == hvalue(t2)) return 1;
else if (L == NULL) return 0;
- tm = get_equalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable, TM_EQ);
+ tm = luaT_getequalTM(L, hvalue(t1)->metatable, hvalue(t2)->metatable);
break; /* will try TM */
}
default:
- lua_assert(iscollectable(t1));
return gcvalue(t1) == gcvalue(t2);
}
if (tm == NULL) return 0; /* no TM? */
- callTM(L, tm, t1, t2, L->top, 1); /* call TM */
+ luaT_callTM(L, tm, t1, t2, L->top, 1); /* call TM */
return !l_isfalse(L->top);
}
@@ -295,10 +269,8 @@ void luaV_concat (lua_State *L, int total) {
do {
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);
- }
+ if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1))
+ luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
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) {
@@ -312,7 +284,7 @@ void luaV_concat (lua_State *L, int total) {
/* collect total length */
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)
+ if (l >= (MAX_SIZE/sizeof(char)) - tl)
luaG_runerror(L, "string length overflow");
tl += l;
}
@@ -334,16 +306,16 @@ void luaV_concat (lua_State *L, int total) {
void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
const TValue *tm;
- switch (ttypenv(rb)) {
+ switch (ttnov(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 */
+ setivalue(ra, luaH_getn(h)); /* else primitive len */
return;
}
case LUA_TSTRING: {
- setnvalue(ra, cast_num(tsvalue(rb)->len));
+ setivalue(ra, tsvalue(rb)->len);
return;
}
default: { /* try metamethod */
@@ -353,21 +325,54 @@ void luaV_objlen (lua_State *L, StkId ra, const TValue *rb) {
break;
}
}
- callTM(L, tm, rb, rb, ra, 1);
+ luaT_callTM(L, tm, rb, rb, ra, 1);
+}
+
+
+lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) {
+ if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
+ if (y == 0)
+ luaG_runerror(L, "attempt to divide by zero");
+ else /* -1 */
+ return -x; /* avoid overflow with 0x80000... */
+ }
+ else {
+ lua_Integer d = x / y; /* perform division */
+ if ((x ^ y) >= 0 || x % y == 0) /* same signal or no rest? */
+ return d;
+ else
+ return d - 1; /* correct 'div' for negative case */
+ }
+}
+
+
+lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) {
+ if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
+ if (y == 0)
+ luaG_runerror(L, "attempt to perform 'n%%0'");
+ else /* -1 */
+ return 0; /* avoid overflow with 0x80000... */
+ }
+ else {
+ lua_Integer r = x % y;
+ if (r == 0 || (x ^ y) >= 0)
+ return r;
+ else
+ return r + y; /* correct 'mod' for negative case */
+ }
}
-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 res = luaO_arith(op - TM_ADD + LUA_OPADD, nvalue(b), nvalue(c));
- setnvalue(ra, res);
+lua_Integer luaV_pow (lua_Integer x, lua_Integer y) {
+ lua_Integer r = 1;
+ lua_assert(y >= 0);
+ if (y == 0) return r;
+ for (; y > 1; y >>= 1) {
+ if (y & 1) r = intop(*, r, x);
+ x = intop(*, x, x);
}
- else if (!call_binTM(L, rb, rc, ra, op))
- luaG_aritherror(L, rb, rc);
+ r = intop(*, r, x);
+ return r;
}
@@ -426,7 +431,7 @@ void luaV_finishOp (lua_State *L) {
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_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:
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);
@@ -446,7 +451,7 @@ void luaV_finishOp (lua_State *L) {
break;
}
case OP_CONCAT: {
- StkId top = L->top - 1; /* top when 'call_binTM' was called */
+ StkId top = L->top - 1; /* top when 'luaT_trybinTM' 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 */
@@ -517,16 +522,6 @@ void luaV_finishOp (lua_State *L) {
luai_threadyield(L); )
-#define arith_op(op,tm) { \
- TValue *rb = RKB(i); \
- TValue *rc = RKC(i); \
- if (ttisnumber(rb) && ttisnumber(rc)) { \
- lua_Number nb = nvalue(rb), nc = nvalue(rc); \
- setnvalue(ra, op(L, nb, nc)); \
- } \
- 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 */
@@ -547,7 +542,7 @@ void luaV_execute (lua_State *L) {
StkId ra;
if ((L->hookmask & (LUA_MASKLINE | LUA_MASKCOUNT)) &&
(--L->hookcount == 0 || L->hookmask & LUA_MASKLINE)) {
- Protect(traceexec(L));
+ Protect(luaG_traceexec(L));
}
/* WARNING: several calls may realloc the stack and invalidate `ra' */
ra = RA(i);
@@ -614,32 +609,103 @@ void luaV_execute (lua_State *L) {
setobjs2s(L, ra+1, rb);
Protect(luaV_gettable(L, rb, RKC(i), ra));
)
- vmcase(OP_ADD,
- arith_op(luai_numadd, TM_ADD);
+ vmcase(OP_ADD,
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Number nb; lua_Number nc;
+ if (ttisinteger(rb) && ttisinteger(rc)) {
+ lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+ setivalue(ra, intop(+, ib, ic));
+ }
+ else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+ setnvalue(ra, luai_numadd(L, nb, nc));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_ADD)); }
)
vmcase(OP_SUB,
- arith_op(luai_numsub, TM_SUB);
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Number nb; lua_Number nc;
+ if (ttisinteger(rb) && ttisinteger(rc)) {
+ lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+ setivalue(ra, intop(-, ib, ic));
+ }
+ else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+ setnvalue(ra, luai_numsub(L, nb, nc));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SUB)); }
)
vmcase(OP_MUL,
- arith_op(luai_nummul, TM_MUL);
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Number nb; lua_Number nc;
+ if (ttisinteger(rb) && ttisinteger(rc)) {
+ lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+ setivalue(ra, intop(*, ib, ic));
+ }
+ else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+ setnvalue(ra, luai_nummul(L, nb, nc));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MUL)); }
)
- vmcase(OP_DIV,
- arith_op(luai_numdiv, TM_DIV);
+ vmcase(OP_DIV, /* float division (always with floats) */
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Number nb; lua_Number nc;
+ if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+ setnvalue(ra, luai_numdiv(L, nb, nc));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_DIV)); }
+ )
+ vmcase(OP_IDIV, /* integer division */
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Integer ib; lua_Integer ic;
+ if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
+ setivalue(ra, luaV_div(L, ib, ic));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); }
)
vmcase(OP_MOD,
- arith_op(luai_nummod, TM_MOD);
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Number nb; lua_Number nc;
+ if (ttisinteger(rb) && ttisinteger(rc)) {
+ lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
+ setivalue(ra, luaV_mod(L, ib, ic));
+ }
+ else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+ setnvalue(ra, luai_nummod(L, nb, nc));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_MOD)); }
)
vmcase(OP_POW,
- arith_op(luai_numpow, TM_POW);
+ TValue *rb = RKB(i);
+ TValue *rc = RKC(i);
+ lua_Number nb; lua_Number nc;
+ lua_Integer ic;
+ if (ttisinteger(rb) && ttisinteger(rc) &&
+ (ic = ivalue(rc)) >= 0) {
+ lua_Integer ib = ivalue(rb);
+ setivalue(ra, luaV_pow(ib, ic));
+ }
+ else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
+ setnvalue(ra, luai_numpow(L, nb, nc));
+ }
+ else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_POW)); }
)
vmcase(OP_UNM,
TValue *rb = RB(i);
- if (ttisnumber(rb)) {
- lua_Number nb = nvalue(rb);
+ lua_Number nb;
+ if (ttisinteger(rb)) {
+ lua_Integer ib = ivalue(rb);
+ setivalue(ra, -ib);
+ }
+ else if (tonumber(rb, &nb)) {
setnvalue(ra, luai_numunm(L, nb));
}
else {
- Protect(luaV_arith(L, ra, rb, rb, TM_UNM));
+ Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
}
)
vmcase(OP_NOT,
@@ -669,7 +735,7 @@ void luaV_execute (lua_State *L) {
TValue *rb = RKB(i);
TValue *rc = RKC(i);
Protect(
- if (cast_int(equalobj(L, rb, rc)) != GETARG_A(i))
+ if (cast_int(luaV_equalobj(L, rb, rc)) != GETARG_A(i))
ci->u.l.savedpc++;
else
donextjump(ci);
@@ -765,27 +831,47 @@ void luaV_execute (lua_State *L) {
}
)
vmcase(OP_FORLOOP,
- lua_Number step = nvalue(ra+2);
- lua_Number idx = luai_numadd(L, nvalue(ra), step); /* increment index */
- lua_Number limit = nvalue(ra+1);
- 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 */
+ if (ttisinteger(ra)) { /* integer count? */
+ lua_Integer step = ivalue(ra + 2);
+ lua_Integer idx = ivalue(ra) + step; /* increment index */
+ lua_Integer limit = ivalue(ra + 1);
+ if ((0 < step) ? (idx <= limit) : (limit <= idx)) {
+ ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
+ setivalue(ra, idx); /* update internal index... */
+ setivalue(ra + 3, idx); /* ...and external index */
+ }
+ }
+ else { /* floating count */
+ lua_Number step = fltvalue(ra + 2);
+ lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */
+ lua_Number limit = fltvalue(ra + 1);
+ 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 */
+ }
}
)
vmcase(OP_FORPREP,
- const TValue *init = ra;
- const TValue *plimit = ra+1;
- const TValue *pstep = ra+2;
- 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(L, nvalue(ra), nvalue(pstep)));
+ TValue *init = ra;
+ TValue *plimit = ra + 1;
+ TValue *pstep = ra + 2;
+ if (ttisinteger(ra) && ttisinteger(ra + 1) && ttisinteger(ra + 2)) {
+ setivalue(ra, ivalue(ra) - ivalue(pstep));
+ }
+ else { /* try with floats */
+ lua_Number ninit; lua_Number nlimit; lua_Number nstep;
+ if (!tonumber(plimit, &nlimit))
+ luaG_runerror(L, LUA_QL("for") " limit must be a number");
+ setnvalue(plimit, nlimit);
+ if (!tonumber(pstep, &nstep))
+ luaG_runerror(L, LUA_QL("for") " step must be a number");
+ setnvalue(pstep, nstep);
+ if (!tonumber(init, &ninit))
+ luaG_runerror(L, LUA_QL("for") " initial value must be a number");
+ setnvalue(ra, luai_numsub(L, ninit, nstep));
+ }
ci->u.l.savedpc += GETARG_sBx(i);
)
vmcasenb(OP_TFORCALL,
diff --git a/src/lvm.h b/src/lvm.h
index 07e25f9c..4f2651d3 100644
--- a/src/lvm.h
+++ b/src/lvm.h
@@ -1,5 +1,5 @@
/*
-** $Id: lvm.h,v 2.18 2013/01/08 14:06:55 roberto Exp $
+** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp $
** Lua virtual machine
** See Copyright Notice in lua.h
*/
@@ -15,20 +15,24 @@
#define tostring(L,o) (ttisstring(o) || (luaV_tostring(L, o)))
-#define tonumber(o,n) (ttisnumber(o) || (((o) = luaV_tonumber(o,n)) != NULL))
+#define tonumber(o,n) \
+ (ttisfloat(o) ? (*(n) = fltvalue(o), 1) : luaV_tonumber_(o,n))
-#define equalobj(L,o1,o2) (ttisequal(o1, o2) && luaV_equalobj_(L, o1, o2))
+#define tointeger(o,i) \
+ (ttisinteger(o) ? (*(i) = ivalue(o), 1) : luaV_tointeger_(o,i))
-#define luaV_rawequalobj(o1,o2) equalobj(NULL,o1,o2)
+#define intop(op,v1,v2) \
+ cast_integer(cast_unsigned(v1) op cast_unsigned(v2))
-
-/* not to called directly */
-LUAI_FUNC int luaV_equalobj_ (lua_State *L, const TValue *t1, const TValue *t2);
+#define luaV_rawequalobj(t1,t2) luaV_equalobj(NULL,t1,t2)
+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_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_tonumber_ (const TValue *obj, lua_Number *n);
+LUAI_FUNC int luaV_tointeger_ (const TValue *obj, lua_Integer *p);
+LUAI_FUNC int luaV_numtointeger (lua_Number n, lua_Integer *p);
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);
@@ -37,8 +41,9 @@ LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key,
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 lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
+LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
+LUAI_FUNC lua_Integer luaV_pow (lua_Integer x, lua_Integer y);
LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
#endif
diff --git a/src/lzio.h b/src/lzio.h
index 08682301..aec0bc12 100644
--- a/src/lzio.h
+++ b/src/lzio.h
@@ -1,5 +1,5 @@
/*
-** $Id: lzio.h,v 1.26 2011/07/15 12:48:03 roberto Exp $
+** $Id: lzio.h,v 1.27 2013/06/07 14:51:10 roberto Exp $
** Buffered streams
** See Copyright Notice in lua.h
*/
@@ -45,7 +45,7 @@ typedef struct Mbuffer {
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 size_t luaZ_read (ZIO* z, void *b, size_t n); /* read next n bytes */
@@ -55,7 +55,7 @@ struct Zio {
size_t n; /* bytes still unread */
const char *p; /* current position in buffer */
lua_Reader reader; /* reader function */
- void* data; /* additional data */
+ void *data; /* additional data */
lua_State *L; /* Lua state (for reader) */
};