History

Lua 5.3.0-work2

Lua Team committed 12 years ago

Commit ad386d91 parent b83a40a60 files · +3280 −2672Browse files

Showing the changes to src (53 of 60 files). Show all

Unified · Split

53 files
  1. src/.fix +1 −1
  2. src/Makefile +5 −4
  3. src/lapi.c +66 −70
  4. src/lauxlib.c +71 −59
  5. src/lauxlib.h +15 −15
  6. src/lbaselib.c +7 −9
  7. src/lbitlib.c +37 −22
  8. src/lcode.c +65 −36
  9. src/lcode.h +7 −3
  10. src/ldblib.c +3 −7
  11. src/ldebug.c +20 −13
  12. src/ldebug.h +2 −2
  13. src/ldo.c +23 −20
  14. src/ldump.c +154 −133
  15. src/lfunc.c +39 −54
  16. src/lfunc.h +24 −3
  17. src/lgc.c +287 −336
  18. src/lgc.h +30 −49
  19. src/linit.c +2 −1
  20. src/liolib.c +61 −58
  21. src/llex.c +80 −42
  22. src/llex.h +3 −1
  23. src/llimits.h +7 −4
  24. src/lmathlib.c +11 −4
  25. src/loadlib.c +15 −19
  26. src/lobject.c +88 −38
  27. src/lobject.h +25 −20
  28. src/lopcodes.c +17 −5
  29. src/lopcodes.h +9 −3
  30. src/loslib.c +42 −18
  31. src/lparser.c +37 −37
  32. src/lparser.h +1 −2
  33. src/lstate.c +53 −32
  34. src/lstate.h +19 −30
  35. src/lstring.c +46 −55
  36. src/lstring.h +3 −5
  37. src/lstrlib.c +222 −5
  38. src/ltable.c +47 −27
  39. src/ltable.h +6 −1
  40. src/ltablib.c +2 −2
  41. src/ltm.c +18 −11
  42. src/ltm.h +10 −4
  43. src/lua.c +69 −31
  44. src/lua.h +25 −21
  45. src/luac.c +1 −1
  46. src/luaconf.h +76 −44
  47. src/lualib.h +4 −1
  48. src/lundump.c +207 −209
  49. src/lundump.h +16 −11
  50. src/lutf8lib.c +240 −0
  51. src/lvm.c +125 −56
  52. src/lvm.h +3 −2
  53. src/lzio.h +2 −1
src/.fix+1−1
@@ -1,2 +1,2 @@
1#define nvalue(x) 01#define nvalue(x) ((lua_Number)0)
2#define ttypenv(x) ttnov(x)2#define ttypenv(x) ttnov(x)
src/Makefile+5−4
@@ -33,7 +33,7 @@ CORE_O= lapi.o lcode.o lctype.o ldebug.o ldo.o ldump.o lfunc.o lgc.o llex.o \ · 32 unmodified lines
33 lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \33 lmem.o lobject.o lopcodes.o lparser.o lstate.o lstring.o ltable.o \
34 ltm.o lundump.o lvm.o lzio.o34 ltm.o lundump.o lvm.o lzio.o
35LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \35LIB_O= lauxlib.o lbaselib.o lbitlib.o lcorolib.o ldblib.o liolib.o \
36 lmathlib.o loslib.o lstrlib.o ltablib.o loadlib.o linit.o36 lmathlib.o loslib.o lstrlib.o ltablib.o lutf8lib.o loadlib.o linit.o
37BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)37BASE_O= $(CORE_O) $(LIB_O) $(MYOBJS)
38 38
39LUA_T= lua39LUA_T= lua
@@ -152,7 +152,7 @@ lgc.o: lgc.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \ · 112 unmodified lines
152linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h152linit.o: linit.c lua.h luaconf.h lualib.h lauxlib.h
153liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h153liolib.o: liolib.c lua.h luaconf.h lauxlib.h lualib.h
154llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \154llex.o: llex.c lua.h luaconf.h lctype.h llimits.h ldo.h lobject.h \
155 lstate.h ltm.h lzio.h lmem.h llex.h lparser.h lstring.h lgc.h ltable.h155 lstate.h ltm.h lzio.h lmem.h lgc.h llex.h lparser.h lstring.h ltable.h
156lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h156lmathlib.o: lmathlib.c lua.h luaconf.h lauxlib.h lualib.h
157lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \157lmem.o: lmem.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
158 ltm.h lzio.h lmem.h ldo.h lgc.h158 ltm.h lzio.h lmem.h ldo.h lgc.h
@@ -167,8 +167,8 @@ lparser.o: lparser.c lua.h luaconf.h lcode.h llex.h lobject.h llimits.h \ · 8 unmodified lines
167lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \167lstate.o: lstate.c lua.h luaconf.h lapi.h llimits.h lstate.h lobject.h \
168 ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \168 ltm.h lzio.h lmem.h ldebug.h ldo.h lfunc.h lgc.h llex.h lstring.h \
169 ltable.h169 ltable.h
170lstring.o: lstring.c lua.h luaconf.h lmem.h llimits.h lobject.h lstate.h \170lstring.o: lstring.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
171 ltm.h lzio.h lstring.h lgc.h171 llimits.h ltm.h lzio.h lmem.h ldo.h lstring.h lgc.h
172lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h172lstrlib.o: lstrlib.c lua.h luaconf.h lauxlib.h lualib.h
173ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \173ltable.o: ltable.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h \
174 ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h174 ltm.h lzio.h lmem.h ldo.h lgc.h lstring.h ltable.h lvm.h
@@ -180,6 +180,7 @@ luac.o: luac.c lua.h luaconf.h lauxlib.h lobject.h llimits.h lstate.h \ · 5 unmodified lines
180 ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h180 ltm.h lzio.h lmem.h lundump.h ldebug.h lopcodes.h
181lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \181lundump.o: lundump.c lua.h luaconf.h ldebug.h lstate.h lobject.h \
182 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h182 llimits.h ltm.h lzio.h lmem.h ldo.h lfunc.h lstring.h lgc.h lundump.h
183lutf8lib.o: lutf8lib.c lua.h luaconf.h lauxlib.h lualib.h
183lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \184lvm.o: lvm.c lua.h luaconf.h ldebug.h lstate.h lobject.h llimits.h ltm.h \
184 lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h185 lzio.h lmem.h ldo.h lfunc.h lgc.h lopcodes.h lstring.h ltable.h lvm.h
185lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \186lzio.o: lzio.c lua.h luaconf.h llimits.h lmem.h lstate.h lobject.h ltm.h \
src/lapi.c+66−70
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lapi.c,v 2.185 2013/07/05 14:29:51 roberto Exp $2** $Id: lapi.c,v 2.201 2014/03/12 20:57:40 roberto Exp $
3** Lua API3** Lua API
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -286,7 +286,7 @@ LUA_API int lua_isstring (lua_State *L, int idx) { · 280 unmodified lines
286 286
287LUA_API int lua_isuserdata (lua_State *L, int idx) {287LUA_API int lua_isuserdata (lua_State *L, int idx) {
288 const TValue *o = index2addr(L, idx);288 const TValue *o = index2addr(L, idx);
289 return (ttisuserdata(o) || ttislightuserdata(o));289 return (ttisfulluserdata(o) || ttislightuserdata(o));
290}290}
291 291
292 292
@@ -299,9 +299,9 @@ LUA_API int lua_rawequal (lua_State *L, int index1, int index2) { · 6 unmodified lines
299 299
300LUA_API void lua_arith (lua_State *L, int op) {300LUA_API void lua_arith (lua_State *L, int op) {
301 lua_lock(L);301 lua_lock(L);
302 if (op != LUA_OPUNM) /* all other operations expect two operands */302 if (op != LUA_OPUNM && op != LUA_OPBNOT)
303 api_checknelems(L, 2);303 api_checknelems(L, 2); /* all other operations expect two operands */
304 else { /* for unary minus, add fake 2nd operand */304 else { /* for unary operations, add fake 2nd operand */
305 api_checknelems(L, 1);305 api_checknelems(L, 1);
306 setobjs2s(L, L->top, L->top - 1);306 setobjs2s(L, L->top, L->top - 1);
307 L->top++;307 L->top++;
@@ -379,20 +379,20 @@ LUA_API lua_Unsigned lua_tounsignedx (lua_State *L, int idx, int *pisnum) { · 71 unmodified lines
379 isnum = 1;379 isnum = 1;
380 break;380 break;
381 }381 }
382 case LUA_TNUMFLT: {382 case LUA_TNUMFLT: { /* compute floor(n) % 2^(numbits in an integer) */
383 const lua_Number twop = (~(lua_Unsigned)0) + cast_num(1);383 const lua_Number twop = cast_num(MAX_UINTEGER) + cast_num(1); /* 2^n */
384 lua_Number n = fltvalue(o);384 lua_Number n = fltvalue(o); /* get value */
385 int neg = 0;385 int neg = 0;
386 n = l_floor(n);386 n = l_floor(n); /* get its floor */
387 if (n < 0) {387 if (n < 0) {
388 neg = 1;388 neg = 1;
389 n = -n;389 n = -n; /* make 'n' positive, so that 'fmod' is the same as '%' */
390 }390 }
391 n = l_mathop(fmod)(n, twop);391 n = l_mathop(fmod)(n, twop); /* n = n % 2^(numbits in an integer) */
392 if (luai_numisnan(L,n)) /* not a number? */392 if (luai_numisnan(n)) /* not a number? */
393 break; /* not an integer, too */393 break; /* not an integer, too */
394 res = cast_unsigned(n);394 res = cast_unsigned(n); /* 'n' now must fit in an unsigned */
395 if (neg) res = 0u - res;395 if (neg) res = 0u - res; /* back to negative, if needed */
396 isnum = 1;396 isnum = 1;
397 break;397 break;
398 }398 }
@@ -586,8 +586,10 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { · 187 unmodified lines
586 cl = luaF_newCclosure(L, n);586 cl = luaF_newCclosure(L, n);
587 cl->c.f = fn;587 cl->c.f = fn;
588 L->top -= n;588 L->top -= n;
589 while (n--)589 while (n--) {
590 setobj2n(L, &cl->c.upvalue[n], L->top + n);590 setobj2n(L, &cl->c.upvalue[n], L->top + n);
591 /* does not need barrier because closure is white */
592 }
591 setclCvalue(L, L->top, cl);593 setclCvalue(L, L->top, cl);
592 }594 }
593 api_incr_top(L);595 api_incr_top(L);
@@ -626,7 +628,7 @@ LUA_API int lua_pushthread (lua_State *L) { · 32 unmodified lines
626*/628*/
627 629
628 630
629LUA_API void lua_getglobal (lua_State *L, const char *var) {631LUA_API int lua_getglobal (lua_State *L, const char *var) {
630 Table *reg = hvalue(&G(L)->l_registry);632 Table *reg = hvalue(&G(L)->l_registry);
631 const TValue *gt; /* global table */633 const TValue *gt; /* global table */
632 lua_lock(L);634 lua_lock(L);
@@ -634,19 +636,21 @@ LUA_API void lua_getglobal (lua_State *L, const char *var) { · 1 unmodified line
634 setsvalue2s(L, L->top++, luaS_new(L, var));636 setsvalue2s(L, L->top++, luaS_new(L, var));
635 luaV_gettable(L, gt, L->top - 1, L->top - 1);637 luaV_gettable(L, gt, L->top - 1, L->top - 1);
636 lua_unlock(L);638 lua_unlock(L);
639 return ttnov(L->top - 1);
637}640}
638 641
639 642
640LUA_API void lua_gettable (lua_State *L, int idx) {643LUA_API int lua_gettable (lua_State *L, int idx) {
641 StkId t;644 StkId t;
642 lua_lock(L);645 lua_lock(L);
643 t = index2addr(L, idx);646 t = index2addr(L, idx);
644 luaV_gettable(L, t, L->top - 1, L->top - 1);647 luaV_gettable(L, t, L->top - 1, L->top - 1);
645 lua_unlock(L);648 lua_unlock(L);
649 return ttnov(L->top - 1);
646}650}
647 651
648 652
649LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {653LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
650 StkId t;654 StkId t;
651 lua_lock(L);655 lua_lock(L);
652 t = index2addr(L, idx);656 t = index2addr(L, idx);
@@ -654,20 +658,22 @@ LUA_API void lua_getfield (lua_State *L, int idx, const char *k) { · 1 unmodified line
654 api_incr_top(L);658 api_incr_top(L);
655 luaV_gettable(L, t, L->top - 1, L->top - 1);659 luaV_gettable(L, t, L->top - 1, L->top - 1);
656 lua_unlock(L);660 lua_unlock(L);
661 return ttnov(L->top - 1);
657}662}
658 663
659 664
660LUA_API void lua_rawget (lua_State *L, int idx) {665LUA_API int lua_rawget (lua_State *L, int idx) {
661 StkId t;666 StkId t;
662 lua_lock(L);667 lua_lock(L);
663 t = index2addr(L, idx);668 t = index2addr(L, idx);
664 api_check(L, ttistable(t), "table expected");669 api_check(L, ttistable(t), "table expected");
665 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));670 setobj2s(L, L->top - 1, luaH_get(hvalue(t), L->top - 1));
666 lua_unlock(L);671 lua_unlock(L);
672 return ttnov(L->top - 1);
667}673}
668 674
669 675
670LUA_API void lua_rawgeti (lua_State *L, int idx, lua_Integer n) {676LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
671 StkId t;677 StkId t;
672 lua_lock(L);678 lua_lock(L);
673 t = index2addr(L, idx);679 t = index2addr(L, idx);
@@ -675,10 +681,11 @@ LUA_API void lua_rawgeti (lua_State *L, int idx, lua_Integer n) { · 1 unmodified line
675 setobj2s(L, L->top, luaH_getint(hvalue(t), n));681 setobj2s(L, L->top, luaH_getint(hvalue(t), n));
676 api_incr_top(L);682 api_incr_top(L);
677 lua_unlock(L);683 lua_unlock(L);
684 return ttnov(L->top - 1);
678}685}
679 686
680 687
681LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) {688LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
682 StkId t;689 StkId t;
683 TValue k;690 TValue k;
684 lua_lock(L);691 lua_lock(L);
@@ -688,6 +695,7 @@ LUA_API void lua_rawgetp (lua_State *L, int idx, const void *p) { · 3 unmodified lines
688 setobj2s(L, L->top, luaH_get(hvalue(t), &k));695 setobj2s(L, L->top, luaH_get(hvalue(t), &k));
689 api_incr_top(L);696 api_incr_top(L);
690 lua_unlock(L);697 lua_unlock(L);
698 return ttnov(L->top - 1);
691}699}
692 700
693 701
@@ -737,11 +745,8 @@ LUA_API void lua_getuservalue (lua_State *L, int idx) { · 43 unmodified lines
737 StkId o;745 StkId o;
738 lua_lock(L);746 lua_lock(L);
739 o = index2addr(L, idx);747 o = index2addr(L, idx);
740 api_check(L, ttisuserdata(o), "userdata expected");748 api_check(L, ttisfulluserdata(o), "full userdata expected");
741 if (uvalue(o)->env) {749 getuservalue(L, rawuvalue(o), L->top);
742 sethvalue(L, L->top, uvalue(o)->env);
743 } else
744 setnilvalue(L->top);
745 api_incr_top(L);750 api_incr_top(L);
746 lua_unlock(L);751 lua_unlock(L);
747}752}
@@ -846,7 +851,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { · 98 unmodified lines
846 case LUA_TTABLE: {851 case LUA_TTABLE: {
847 hvalue(obj)->metatable = mt;852 hvalue(obj)->metatable = mt;
848 if (mt) {853 if (mt) {
849 luaC_objbarrierback(L, gcvalue(obj), mt);854 luaC_objbarrier(L, gcvalue(obj), mt);
850 luaC_checkfinalizer(L, gcvalue(obj), mt);855 luaC_checkfinalizer(L, gcvalue(obj), mt);
851 }856 }
852 break;857 break;
@@ -875,14 +880,9 @@ LUA_API void lua_setuservalue (lua_State *L, int idx) { · 22 unmodified lines
875 lua_lock(L);880 lua_lock(L);
876 api_checknelems(L, 1);881 api_checknelems(L, 1);
877 o = index2addr(L, idx);882 o = index2addr(L, idx);
878 api_check(L, ttisuserdata(o), "userdata expected");883 api_check(L, ttisfulluserdata(o), "full userdata expected");
879 if (ttisnil(L->top - 1))884 setuservalue(L, rawuvalue(o), L->top - 1);
880 uvalue(o)->env = NULL;885 luaC_barrier(L, gcvalue(o), L->top - 1);
881 else {
882 api_check(L, ttistable(L->top - 1), "table expected");
883 uvalue(o)->env = hvalue(L->top - 1);
884 luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
885 }
886 L->top--;886 L->top--;
887 lua_unlock(L);887 lua_unlock(L);
888}888}
@@ -1015,14 +1015,14 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, · 126 unmodified lines
1015}1015}
1016 1016
1017 1017
1018LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {1018LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data, int strip) {
1019 int status;1019 int status;
1020 TValue *o;1020 TValue *o;
1021 lua_lock(L);1021 lua_lock(L);
1022 api_checknelems(L, 1);1022 api_checknelems(L, 1);
1023 o = L->top - 1;1023 o = L->top - 1;
1024 if (isLfunction(o))1024 if (isLfunction(o))
1025 status = luaU_dump(L, getproto(o), writer, data, 0);1025 status = luaU_dump(L, getproto(o), writer, data, strip);
1026 else1026 else
1027 status = 1;1027 status = 1;
1028 lua_unlock(L);1028 lua_unlock(L);
@@ -1068,19 +1068,21 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 39 unmodified lines
1068 break;1068 break;
1069 }1069 }
1070 case LUA_GCSTEP: {1070 case LUA_GCSTEP: {
1071 if (g->gckind == KGC_GEN) { /* generational mode? */1071 l_mem debt = 1; /* =1 to signal that it did an actual step */
1072 res = (g->GCestimate == 0); /* true if it will do major collection */1072 int oldrunning = g->gcrunning;
1073 luaC_forcestep(L); /* do a single step */1073 g->gcrunning = 1; /* force GC to run */
1074 if (data == 0) {
1075 luaE_setdebt(g, -GCSTEPSIZE); /* to do a "small" step */
1076 luaC_step(L);
1074 }1077 }
1075 else {1078 else { /* add 'data' to total debt */
1076 lu_mem debt = cast(lu_mem, data) * 1024 - GCSTEPSIZE;1079 debt = cast(l_mem, data) * 1024 + g->GCdebt;
1077 if (g->gcrunning)1080 luaE_setdebt(g, debt);
1078 debt += g->GCdebt; /* include current debt */1081 luaC_checkGC(L);
1079 luaE_setdebt(g, debt);
1080 luaC_forcestep(L);
1081 if (g->gcstate == GCSpause) /* end of cycle? */
1082 res = 1; /* signal it */
1083 }1082 }
1083 g->gcrunning = oldrunning; /* restore previous state */
1084 if (debt > 0 && g->gcstate == GCSpause) /* end of cycle? */
1085 res = 1; /* signal it */
1084 break;1086 break;
1085 }1087 }
1086 case LUA_GCSETPAUSE: {1088 case LUA_GCSETPAUSE: {
@@ -1088,13 +1090,9 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 1 unmodified line
1088 g->gcpause = data;1090 g->gcpause = data;
1089 break;1091 break;
1090 }1092 }
1091 case LUA_GCSETMAJORINC: {
1092 res = g->gcmajorinc;
1093 g->gcmajorinc = data;
1094 break;
1095 }
1096 case LUA_GCSETSTEPMUL: {1093 case LUA_GCSETSTEPMUL: {
1097 res = g->gcstepmul;1094 res = g->gcstepmul;
1095 if (data < 40) data = 40; /* avoid ridiculous low values (and 0) */
1098 g->gcstepmul = data;1096 g->gcstepmul = data;
1099 break;1097 break;
1100 }1098 }
@@ -1102,14 +1100,6 @@ LUA_API int lua_gc (lua_State *L, int what, int data) { · 1 unmodified line
1102 res = g->gcrunning;1100 res = g->gcrunning;
1103 break;1101 break;
1104 }1102 }
1105 case LUA_GCGEN: { /* change collector to generational mode */
1106 luaC_changemode(L, KGC_GEN);
1107 break;
1108 }
1109 case LUA_GCINC: { /* change collector to incremental mode */
1110 luaC_changemode(L, KGC_NORMAL);
1111 break;
1112 }
1113 default: res = -1; /* invalid option */1103 default: res = -1; /* invalid option */
1114 }1104 }
1115 lua_unlock(L);1105 lua_unlock(L);
@@ -1197,7 +1187,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 81 unmodified lines
1197 Udata *u;1187 Udata *u;
1198 lua_lock(L);1188 lua_lock(L);
1199 luaC_checkGC(L);1189 luaC_checkGC(L);
1200 u = luaS_newudata(L, size, NULL);1190 u = luaS_newudata(L, size);
1201 setuvalue(L, L->top, u);1191 setuvalue(L, L->top, u);
1202 api_incr_top(L);1192 api_incr_top(L);
1203 lua_unlock(L);1193 lua_unlock(L);
@@ -1207,7 +1197,7 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) { · 3 unmodified lines
1207 1197
1208 1198
1209static const char *aux_upvalue (StkId fi, int n, TValue **val,1199static const char *aux_upvalue (StkId fi, int n, TValue **val,
1210 GCObject **owner) {1200 GCObject **owner, UpVal **uv) {
1211 switch (ttype(fi)) {1201 switch (ttype(fi)) {
1212 case LUA_TCCL: { /* C closure */1202 case LUA_TCCL: { /* C closure */
1213 CClosure *f = clCvalue(fi);1203 CClosure *f = clCvalue(fi);
@@ -1222,9 +1212,9 @@ static const char *aux_upvalue (StkId fi, int n, TValue **val, · 8 unmodified lines
1222 Proto *p = f->p;1212 Proto *p = f->p;
1223 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;1213 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1224 *val = f->upvals[n-1]->v;1214 *val = f->upvals[n-1]->v;
1225 if (owner) *owner = obj2gco(f->upvals[n - 1]);1215 if (uv) *uv = f->upvals[n - 1];
1226 name = p->upvalues[n-1].name;1216 name = p->upvalues[n-1].name;
1227 return (name == NULL) ? "" : getstr(name);1217 return (name == NULL) ? "(*no name)" : getstr(name);
1228 }1218 }
1229 default: return NULL; /* not a closure */1219 default: return NULL; /* not a closure */
1230 }1220 }
@@ -1235,7 +1225,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { · 4 unmodified lines
1235 const char *name;1225 const char *name;
1236 TValue *val = NULL; /* to avoid warnings */1226 TValue *val = NULL; /* to avoid warnings */
1237 lua_lock(L);1227 lua_lock(L);
1238 name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);1228 name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL, NULL);
1239 if (name) {1229 if (name) {
1240 setobj2s(L, L->top, val);1230 setobj2s(L, L->top, val);
1241 api_incr_top(L);1231 api_incr_top(L);
@@ -1248,16 +1238,18 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) { · 6 unmodified lines
1248LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {1238LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1249 const char *name;1239 const char *name;
1250 TValue *val = NULL; /* to avoid warnings */1240 TValue *val = NULL; /* to avoid warnings */
1251 GCObject *owner = NULL; /* to avoid warnings */1241 GCObject *owner = NULL;
1242 UpVal *uv = NULL;
1252 StkId fi;1243 StkId fi;
1253 lua_lock(L);1244 lua_lock(L);
1254 fi = index2addr(L, funcindex);1245 fi = index2addr(L, funcindex);
1255 api_checknelems(L, 1);1246 api_checknelems(L, 1);
1256 name = aux_upvalue(fi, n, &val, &owner);1247 name = aux_upvalue(fi, n, &val, &owner, &uv);
1257 if (name) {1248 if (name) {
1258 L->top--;1249 L->top--;
1259 setobj(L, val, L->top);1250 setobj(L, val, L->top);
1260 luaC_barrier(L, owner, L->top);1251 if (owner) { luaC_barrier(L, owner, L->top); }
1252 else if (uv) { luaC_upvalbarrier(L, uv); }
1261 }1253 }
1262 lua_unlock(L);1254 lua_unlock(L);
1263 return name;1255 return name;
@@ -1299,7 +1291,11 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, · 35 unmodified lines
1299 LClosure *f1;1291 LClosure *f1;
1300 UpVal **up1 = getupvalref(L, fidx1, n1, &f1);1292 UpVal **up1 = getupvalref(L, fidx1, n1, &f1);
1301 UpVal **up2 = getupvalref(L, fidx2, n2, NULL);1293 UpVal **up2 = getupvalref(L, fidx2, n2, NULL);
1294 luaC_upvdeccount(L, *up1);
1302 *up1 = *up2;1295 *up1 = *up2;
1303 luaC_objbarrier(L, f1, *up2);1296 (*up1)->refcount++;
1297 if (upisopen(*up1)) (*up1)->u.open.touched = 1;
1298 luaC_upvalbarrier(L, *up1);
1304}1299}
1305 1300
1301
src/lauxlib.c+71−59
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lauxlib.c,v 1.255 2013/06/27 18:32:33 roberto Exp $2** $Id: lauxlib.c,v 1.260 2014/03/12 20:57:40 roberto Exp $
3** Auxiliary functions for building Lua libraries3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -150,33 +150,40 @@ LUALIB_API void luaL_traceback (lua_State *L, lua_State *L1, · 144 unmodified lines
150** =======================================================150** =======================================================
151*/151*/
152 152
153LUALIB_API int luaL_argerror (lua_State *L, int narg, const char *extramsg) {153LUALIB_API int luaL_argerror (lua_State *L, int arg, const char *extramsg) {
154 lua_Debug ar;154 lua_Debug ar;
155 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */155 if (!lua_getstack(L, 0, &ar)) /* no stack frame? */
156 return luaL_error(L, "bad argument #%d (%s)", narg, extramsg);156 return luaL_error(L, "bad argument #%d (%s)", arg, extramsg);
157 lua_getinfo(L, "n", &ar);157 lua_getinfo(L, "n", &ar);
158 if (strcmp(ar.namewhat, "method") == 0) {158 if (strcmp(ar.namewhat, "method") == 0) {
159 narg--; /* do not count `self' */159 arg--; /* do not count `self' */
160 if (narg == 0) /* error is in the self argument itself? */160 if (arg == 0) /* error is in the self argument itself? */
161 return luaL_error(L, "calling " LUA_QS " on bad self (%s)",161 return luaL_error(L, "calling " LUA_QS " on bad self (%s)",
162 ar.name, extramsg);162 ar.name, extramsg);
163 }163 }
164 if (ar.name == NULL)164 if (ar.name == NULL)
165 ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";165 ar.name = (pushglobalfuncname(L, &ar)) ? lua_tostring(L, -1) : "?";
166 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",166 return luaL_error(L, "bad argument #%d to " LUA_QS " (%s)",
167 narg, ar.name, extramsg);167 arg, ar.name, extramsg);
168}168}
169 169
170 170
171static int typeerror (lua_State *L, int narg, const char *tname) {171static int typeerror (lua_State *L, int arg, const char *tname) {
172 const char *msg = lua_pushfstring(L, "%s expected, got %s",172 const char *msg;
173 tname, luaL_typename(L, narg));173 const char *typearg = luaL_typename(L, arg);
174 return luaL_argerror(L, narg, msg);174 if (lua_getmetatable(L, arg)) {
175 if (lua_getfield(L, -1, "__name") == LUA_TSTRING)
176 typearg = lua_tostring(L, -1);
177 }
178 else if (lua_type(L, arg) == LUA_TLIGHTUSERDATA)
179 typearg = "light userdata";
180 msg = lua_pushfstring(L, "%s expected, got %s", tname, typearg);
181 return luaL_argerror(L, arg, msg);
175}182}
176 183
177 184
178static void tag_error (lua_State *L, int narg, int tag) {185static void tag_error (lua_State *L, int arg, int tag) {
179 typeerror(L, narg, lua_typename(L, tag));186 typeerror(L, arg, lua_typename(L, tag));
180}187}
181 188
182 189
@@ -275,6 +282,8 @@ LUALIB_API int luaL_newmetatable (lua_State *L, const char *tname) { · 92 unmodified lines
275 return 0; /* leave previous value on top, but return 0 */282 return 0; /* leave previous value on top, but return 0 */
276 lua_pop(L, 1);283 lua_pop(L, 1);
277 lua_newtable(L); /* create metatable */284 lua_newtable(L); /* create metatable */
285 lua_pushstring(L, tname);
286 lua_setfield(L, -2, "__name"); /* metatable.__name = tname */
278 lua_pushvalue(L, -1);287 lua_pushvalue(L, -1);
279 lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */288 lua_setfield(L, LUA_REGISTRYINDEX, tname); /* registry.name = metatable */
280 return 1;289 return 1;
@@ -317,15 +326,15 @@ LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname) { · 36 unmodified lines
317** =======================================================326** =======================================================
318*/327*/
319 328
320LUALIB_API int luaL_checkoption (lua_State *L, int narg, const char *def,329LUALIB_API int luaL_checkoption (lua_State *L, int arg, const char *def,
321 const char *const lst[]) {330 const char *const lst[]) {
322 const char *name = (def) ? luaL_optstring(L, narg, def) :331 const char *name = (def) ? luaL_optstring(L, arg, def) :
323 luaL_checkstring(L, narg);332 luaL_checkstring(L, arg);
324 int i;333 int i;
325 for (i=0; lst[i]; i++)334 for (i=0; lst[i]; i++)
326 if (strcmp(lst[i], name) == 0)335 if (strcmp(lst[i], name) == 0)
327 return i;336 return i;
328 return luaL_argerror(L, narg,337 return luaL_argerror(L, arg,
329 lua_pushfstring(L, "invalid option " LUA_QS, name));338 lua_pushfstring(L, "invalid option " LUA_QS, name));
330}339}
331 340
@@ -342,86 +351,86 @@ LUALIB_API void luaL_checkstack (lua_State *L, int space, const char *msg) { · 10 unmodified lines
342}351}
343 352
344 353
345LUALIB_API void luaL_checktype (lua_State *L, int narg, int t) {354LUALIB_API void luaL_checktype (lua_State *L, int arg, int t) {
346 if (lua_type(L, narg) != t)355 if (lua_type(L, arg) != t)
347 tag_error(L, narg, t);356 tag_error(L, arg, t);
348}357}
349 358
350 359
351LUALIB_API void luaL_checkany (lua_State *L, int narg) {360LUALIB_API void luaL_checkany (lua_State *L, int arg) {
352 if (lua_type(L, narg) == LUA_TNONE)361 if (lua_type(L, arg) == LUA_TNONE)
353 luaL_argerror(L, narg, "value expected");362 luaL_argerror(L, arg, "value expected");
354}363}
355 364
356 365
357LUALIB_API const char *luaL_checklstring (lua_State *L, int narg, size_t *len) {366LUALIB_API const char *luaL_checklstring (lua_State *L, int arg, size_t *len) {
358 const char *s = lua_tolstring(L, narg, len);367 const char *s = lua_tolstring(L, arg, len);
359 if (!s) tag_error(L, narg, LUA_TSTRING);368 if (!s) tag_error(L, arg, LUA_TSTRING);
360 return s;369 return s;
361}370}
362 371
363 372
364LUALIB_API const char *luaL_optlstring (lua_State *L, int narg,373LUALIB_API const char *luaL_optlstring (lua_State *L, int arg,
365 const char *def, size_t *len) {374 const char *def, size_t *len) {
366 if (lua_isnoneornil(L, narg)) {375 if (lua_isnoneornil(L, arg)) {
367 if (len)376 if (len)
368 *len = (def ? strlen(def) : 0);377 *len = (def ? strlen(def) : 0);
369 return def;378 return def;
370 }379 }
371 else return luaL_checklstring(L, narg, len);380 else return luaL_checklstring(L, arg, len);
372}381}
373 382
374 383
375LUALIB_API lua_Number luaL_checknumber (lua_State *L, int narg) {384LUALIB_API lua_Number luaL_checknumber (lua_State *L, int arg) {
376 int isnum;385 int isnum;
377 lua_Number d = lua_tonumberx(L, narg, &isnum);386 lua_Number d = lua_tonumberx(L, arg, &isnum);
378 if (!isnum)387 if (!isnum)
379 tag_error(L, narg, LUA_TNUMBER);388 tag_error(L, arg, LUA_TNUMBER);
380 return d;389 return d;
381}390}
382 391
383 392
384LUALIB_API lua_Number luaL_optnumber (lua_State *L, int narg, lua_Number def) {393LUALIB_API lua_Number luaL_optnumber (lua_State *L, int arg, lua_Number def) {
385 return luaL_opt(L, luaL_checknumber, narg, def);394 return luaL_opt(L, luaL_checknumber, arg, def);
386}395}
387 396
388 397
389static void interror (lua_State *L, int narg) {398static void interror (lua_State *L, int arg) {
390 if (lua_type(L, narg) == LUA_TNUMBER)399 if (lua_type(L, arg) == LUA_TNUMBER)
391 luaL_argerror(L, narg, "float value out of range");400 luaL_argerror(L, arg, "float value out of range");
392 else401 else
393 tag_error(L, narg, LUA_TNUMBER);402 tag_error(L, arg, LUA_TNUMBER);
394}403}
395 404
396 405
397LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int narg) {406LUALIB_API lua_Integer luaL_checkinteger (lua_State *L, int arg) {
398 int isnum;407 int isnum;
399 lua_Integer d = lua_tointegerx(L, narg, &isnum);408 lua_Integer d = lua_tointegerx(L, arg, &isnum);
400 if (!isnum) {409 if (!isnum) {
401 interror(L, narg);410 interror(L, arg);
402 }411 }
403 return d;412 return d;
404}413}
405 414
406 415
407LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int narg) {416LUALIB_API lua_Unsigned luaL_checkunsigned (lua_State *L, int arg) {
408 int isnum;417 int isnum;
409 lua_Unsigned d = lua_tounsignedx(L, narg, &isnum);418 lua_Unsigned d = lua_tounsignedx(L, arg, &isnum);
410 if (!isnum)419 if (!isnum)
411 interror(L, narg);420 interror(L, arg);
412 return d;421 return d;
413}422}
414 423
415 424
416LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int narg,425LUALIB_API lua_Integer luaL_optinteger (lua_State *L, int arg,
417 lua_Integer def) {426 lua_Integer def) {
418 return luaL_opt(L, luaL_checkinteger, narg, def);427 return luaL_opt(L, luaL_checkinteger, arg, def);
419}428}
420 429
421 430
422LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int narg,431LUALIB_API lua_Unsigned luaL_optunsigned (lua_State *L, int arg,
423 lua_Unsigned def) {432 lua_Unsigned def) {
424 return luaL_opt(L, luaL_checkunsigned, narg, def);433 return luaL_opt(L, luaL_checkunsigned, arg, def);
425}434}
426 435
427/* }====================================================== */436/* }====================================================== */
@@ -709,8 +718,7 @@ LUALIB_API int luaL_getmetafield (lua_State *L, int obj, const char *event) { · 281 unmodified lines
709 if (!lua_getmetatable(L, obj)) /* no metatable? */718 if (!lua_getmetatable(L, obj)) /* no metatable? */
710 return 0;719 return 0;
711 lua_pushstring(L, event);720 lua_pushstring(L, event);
712 lua_rawget(L, -2);721 if (lua_rawget(L, -2) == LUA_TNIL) { /* is metafield nil? */
713 if (lua_isnil(L, -1)) {
714 lua_pop(L, 2); /* remove metatable and metafield */722 lua_pop(L, 2); /* remove metatable and metafield */
715 return 0;723 return 0;
716 }724 }
@@ -746,10 +754,16 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { · 29 unmodified lines
746LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {754LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
747 if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */755 if (!luaL_callmeta(L, idx, "__tostring")) { /* no metafield? */
748 switch (lua_type(L, idx)) {756 switch (lua_type(L, idx)) {
749 case LUA_TNUMBER: { /* concatenate with empty string to convert */757 case LUA_TNUMBER: {
750 lua_pushvalue(L, idx);758 if (lua_isinteger(L, idx))
751 lua_pushliteral(L, "");759 lua_pushfstring(L, "%I", lua_tointeger(L, idx));
752 lua_concat(L, 2);760 else {
761 const char *s = lua_pushfstring(L, "%f", lua_tonumber(L, idx));
762 if (s[strspn(s, "-0123456789")] == '\0') { /* looks like an int? */
763 lua_pushliteral(L, ".0"); /* add a '.0' to result */
764 lua_concat(L, 2);
765 }
766 }
753 break;767 break;
754 }768 }
755 case LUA_TSTRING:769 case LUA_TSTRING:
@@ -786,8 +800,7 @@ static const char *luaL_findtable (lua_State *L, int idx, · 30 unmodified lines
786 e = strchr(fname, '.');800 e = strchr(fname, '.');
787 if (e == NULL) e = fname + strlen(fname);801 if (e == NULL) e = fname + strlen(fname);
788 lua_pushlstring(L, fname, e - fname);802 lua_pushlstring(L, fname, e - fname);
789 lua_rawget(L, -2);803 if (lua_rawget(L, -2) == LUA_TNIL) { /* no such field? */
790 if (lua_isnil(L, -1)) { /* no such field? */
791 lua_pop(L, 1); /* remove this nil */804 lua_pop(L, 1); /* remove this nil */
792 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */805 lua_createtable(L, 0, (*e == '.' ? 1 : szhint)); /* new table for field */
793 lua_pushlstring(L, fname, e - fname);806 lua_pushlstring(L, fname, e - fname);
@@ -824,8 +837,7 @@ static int libsize (const luaL_Reg *l) { · 30 unmodified lines
824LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,837LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
825 int sizehint) {838 int sizehint) {
826 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */839 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */
827 lua_getfield(L, -1, modname); /* get _LOADED[modname] */840 if (lua_getfield(L, -1, modname) != LUA_TTABLE) { /* no _LOADED[modname]? */
828 if (!lua_istable(L, -1)) { /* not found? */
829 lua_pop(L, 1); /* remove previous result */841 lua_pop(L, 1); /* remove previous result */
830 /* try global variable (and create one if it does not exist) */842 /* try global variable (and create one if it does not exist) */
831 lua_pushglobaltable(L);843 lua_pushglobaltable(L);
@@ -877,8 +889,8 @@ LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { · 45 unmodified lines
877** into the stack889** into the stack
878*/890*/
879LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {891LUALIB_API int luaL_getsubtable (lua_State *L, int idx, const char *fname) {
880 lua_getfield(L, idx, fname);892 if (lua_getfield(L, idx, fname) == LUA_TTABLE)
881 if (lua_istable(L, -1)) return 1; /* table already there */893 return 1; /* table already there */
882 else {894 else {
883 lua_pop(L, 1); /* remove previous result */895 lua_pop(L, 1); /* remove previous result */
884 idx = lua_absindex(L, idx);896 idx = lua_absindex(L, idx);
src/lauxlib.h+15−15
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lauxlib.h,v 1.122 2013/06/27 18:32:33 roberto Exp $2** $Id: lauxlib.h,v 1.123 2014/01/05 14:04:46 roberto Exp $
3** Auxiliary functions for building Lua libraries3** Auxiliary functions for building Lua libraries
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -35,24 +35,24 @@ LUALIB_API void (luaL_checkversion_) (lua_State *L, int ver, size_t sz); · 29 unmodified lines
35LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);35LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e);
36LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);36LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e);
37LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);37LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len);
38LUALIB_API int (luaL_argerror) (lua_State *L, int numarg, const char *extramsg);38LUALIB_API int (luaL_argerror) (lua_State *L, int arg, const char *extramsg);
39LUALIB_API const char *(luaL_checklstring) (lua_State *L, int numArg,39LUALIB_API const char *(luaL_checklstring) (lua_State *L, int arg,
40 size_t *l);40 size_t *l);
41LUALIB_API const char *(luaL_optlstring) (lua_State *L, int numArg,41LUALIB_API const char *(luaL_optlstring) (lua_State *L, int arg,
42 const char *def, size_t *l);42 const char *def, size_t *l);
43LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int numArg);43LUALIB_API lua_Number (luaL_checknumber) (lua_State *L, int arg);
44LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int nArg, lua_Number def);44LUALIB_API lua_Number (luaL_optnumber) (lua_State *L, int arg, lua_Number def);
45 45
46LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int numArg);46LUALIB_API lua_Integer (luaL_checkinteger) (lua_State *L, int arg);
47LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int nArg,47LUALIB_API lua_Integer (luaL_optinteger) (lua_State *L, int arg,
48 lua_Integer def);48 lua_Integer def);
49LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int numArg);49LUALIB_API lua_Unsigned (luaL_checkunsigned) (lua_State *L, int arg);
50LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int numArg,50LUALIB_API lua_Unsigned (luaL_optunsigned) (lua_State *L, int arg,
51 lua_Unsigned def);51 lua_Unsigned def);
52 52
53LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);53LUALIB_API void (luaL_checkstack) (lua_State *L, int sz, const char *msg);
54LUALIB_API void (luaL_checktype) (lua_State *L, int narg, int t);54LUALIB_API void (luaL_checktype) (lua_State *L, int arg, int t);
55LUALIB_API void (luaL_checkany) (lua_State *L, int narg);55LUALIB_API void (luaL_checkany) (lua_State *L, int arg);
56 56
57LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);57LUALIB_API int (luaL_newmetatable) (lua_State *L, const char *tname);
58LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);58LUALIB_API void (luaL_setmetatable) (lua_State *L, const char *tname);
@@ -62,7 +62,7 @@ LUALIB_API void *(luaL_checkudata) (lua_State *L, int ud, const char *tname); · 3 unmodified lines
62LUALIB_API void (luaL_where) (lua_State *L, int lvl);62LUALIB_API void (luaL_where) (lua_State *L, int lvl);
63LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);63LUALIB_API int (luaL_error) (lua_State *L, const char *fmt, ...);
64 64
65LUALIB_API int (luaL_checkoption) (lua_State *L, int narg, const char *def,65LUALIB_API int (luaL_checkoption) (lua_State *L, int arg, const char *def,
66 const char *const lst[]);66 const char *const lst[]);
67 67
68LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);68LUALIB_API int (luaL_fileresult) (lua_State *L, int stat, const char *fname);
@@ -114,8 +114,8 @@ LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, · 45 unmodified lines
114#define luaL_newlib(L,l) \114#define luaL_newlib(L,l) \
115 (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))115 (luaL_checkversion(L), luaL_newlibtable(L,l), luaL_setfuncs(L,l,0))
116 116
117#define luaL_argcheck(L, cond,numarg,extramsg) \117#define luaL_argcheck(L, cond,arg,extramsg) \
118 ((void)((cond) || luaL_argerror(L, (numarg), (extramsg))))118 ((void)((cond) || luaL_argerror(L, (arg), (extramsg))))
119#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))119#define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL))
120#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))120#define luaL_optstring(L,n,d) (luaL_optlstring(L, (n), (d), NULL))
121#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))121#define luaL_checkint(L,n) ((int)luaL_checkinteger(L, (n)))
src/lbaselib.c+7−9
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lbaselib.c,v 1.279 2013/07/05 14:39:15 roberto Exp $2** $Id: lbaselib.c,v 1.285 2014/03/12 20:57:40 roberto Exp $
3** Basic library3** Basic library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -63,7 +63,7 @@ static int b_str2int (const char *s, const char *e, int base, lua_Integer *pn) { · 57 unmodified lines
63 s += strspn(s, SPACECHARS); /* skip trailing spaces */63 s += strspn(s, SPACECHARS); /* skip trailing spaces */
64 if (s != e) /* invalid trailing characters? */64 if (s != e) /* invalid trailing characters? */
65 return 0;65 return 0;
66 *pn = (neg) ? -(lua_Integer)n : (lua_Integer)n;66 *pn = (lua_Integer)((neg) ? (0u - n) : n);
67 return 1;67 return 1;
68}68}
69 69
@@ -175,19 +175,18 @@ static int luaB_rawset (lua_State *L) { · 105 unmodified lines
175static int luaB_collectgarbage (lua_State *L) {175static int luaB_collectgarbage (lua_State *L) {
176 static const char *const opts[] = {"stop", "restart", "collect",176 static const char *const opts[] = {"stop", "restart", "collect",
177 "count", "step", "setpause", "setstepmul",177 "count", "step", "setpause", "setstepmul",
178 "setmajorinc", "isrunning", "generational", "incremental", NULL};178 "isrunning", NULL};
179 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,179 static const int optsnum[] = {LUA_GCSTOP, LUA_GCRESTART, LUA_GCCOLLECT,
180 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,180 LUA_GCCOUNT, LUA_GCSTEP, LUA_GCSETPAUSE, LUA_GCSETSTEPMUL,
181 LUA_GCSETMAJORINC, LUA_GCISRUNNING, LUA_GCGEN, LUA_GCINC};181 LUA_GCISRUNNING};
182 int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];182 int o = optsnum[luaL_checkoption(L, 1, "collect", opts)];
183 int ex = luaL_optint(L, 2, 0);183 int ex = luaL_optint(L, 2, 0);
184 int res = lua_gc(L, o, ex);184 int res = lua_gc(L, o, ex);
185 switch (o) {185 switch (o) {
186 case LUA_GCCOUNT: {186 case LUA_GCCOUNT: {
187 int b = lua_gc(L, LUA_GCCOUNTB, 0);187 int b = lua_gc(L, LUA_GCCOUNTB, 0);
188 lua_pushnumber(L, res + ((lua_Number)b/1024));188 lua_pushnumber(L, (lua_Number)res + ((lua_Number)b/1024));
189 lua_pushinteger(L, b);189 return 1;
190 return 2;
191 }190 }
192 case LUA_GCSTEP: case LUA_GCISRUNNING: {191 case LUA_GCSTEP: case LUA_GCISRUNNING: {
193 lua_pushboolean(L, res);192 lua_pushboolean(L, res);
@@ -247,8 +246,7 @@ static int ipairsaux (lua_State *L) { · 53 unmodified lines
247 luaL_checktype(L, 1, LUA_TTABLE);246 luaL_checktype(L, 1, LUA_TTABLE);
248 i++; /* next value */247 i++; /* next value */
249 lua_pushinteger(L, i);248 lua_pushinteger(L, i);
250 lua_rawgeti(L, 1, i);249 return (lua_rawgeti(L, 1, i) == LUA_TNIL) ? 1 : 2;
251 return (lua_isnil(L, -1)) ? 1 : 2;
252}250}
253 251
254 252
src/lbitlib.c+37−22
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lbitlib.c,v 1.20 2013/06/21 17:27:24 roberto Exp $2** $Id: lbitlib.c,v 1.25 2014/03/20 19:22:16 roberto Exp $
3** Standard library for bitwise operations3** Standard library for bitwise operations
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -13,17 +13,21 @@ · 7 unmodified lines
13#include "lualib.h"13#include "lualib.h"
14 14
15 15
16#if defined(LUA_COMPAT_BITLIB) /* { */
17
18
16/* number of bits to consider in a number */19/* number of bits to consider in a number */
17#if !defined(LUA_NBITS)20#if !defined(LUA_NBITS)
18#define LUA_NBITS 3221#define LUA_NBITS 32
19#endif22#endif
20 23
21 24
22/* type with (at least) LUA_NBITS bits */25/*
23typedef unsigned long b_uint;26** a lua_Unsigned with its first LUA_NBITS bits equal to 1. (Shift must
24 27** be made in two parts to avoid problems when LUA_NBITS is equal to the
25 28** number of bits in a lua_Unsigned.)
26#define ALLONES (~(((~(b_uint)0) << (LUA_NBITS - 1)) << 1))29*/
30#define ALLONES (~(((~(lua_Unsigned)0) << (LUA_NBITS - 1)) << 1))
27 31
28 32
29/* macro to trim extra bits */33/* macro to trim extra bits */
@@ -35,9 +39,9 @@ typedef unsigned long b_uint; · 5 unmodified lines
35 39
36 40
37 41
38static b_uint andaux (lua_State *L) {42static lua_Unsigned andaux (lua_State *L) {
39 int i, n = lua_gettop(L);43 int i, n = lua_gettop(L);
40 b_uint r = ~(b_uint)0;44 lua_Unsigned r = ~(lua_Unsigned)0;
41 for (i = 1; i <= n; i++)45 for (i = 1; i <= n; i++)
42 r &= luaL_checkunsigned(L, i);46 r &= luaL_checkunsigned(L, i);
43 return trim(r);47 return trim(r);
@@ -45,14 +49,14 @@ static b_uint andaux (lua_State *L) { · 1 unmodified line
45 49
46 50
47static int b_and (lua_State *L) {51static int b_and (lua_State *L) {
48 b_uint r = andaux(L);52 lua_Unsigned r = andaux(L);
49 lua_pushunsigned(L, r);53 lua_pushunsigned(L, r);
50 return 1;54 return 1;
51}55}
52 56
53 57
54static int b_test (lua_State *L) {58static int b_test (lua_State *L) {
55 b_uint r = andaux(L);59 lua_Unsigned r = andaux(L);
56 lua_pushboolean(L, r != 0);60 lua_pushboolean(L, r != 0);
57 return 1;61 return 1;
58}62}
@@ -60,7 +64,7 @@ static int b_test (lua_State *L) { · 1 unmodified line
60 64
61static int b_or (lua_State *L) {65static int b_or (lua_State *L) {
62 int i, n = lua_gettop(L);66 int i, n = lua_gettop(L);
63 b_uint r = 0;67 lua_Unsigned r = 0;
64 for (i = 1; i <= n; i++)68 for (i = 1; i <= n; i++)
65 r |= luaL_checkunsigned(L, i);69 r |= luaL_checkunsigned(L, i);
66 lua_pushunsigned(L, trim(r));70 lua_pushunsigned(L, trim(r));
@@ -70,7 +74,7 @@ static int b_or (lua_State *L) { · 3 unmodified lines
70 74
71static int b_xor (lua_State *L) {75static int b_xor (lua_State *L) {
72 int i, n = lua_gettop(L);76 int i, n = lua_gettop(L);
73 b_uint r = 0;77 lua_Unsigned r = 0;
74 for (i = 1; i <= n; i++)78 for (i = 1; i <= n; i++)
75 r ^= luaL_checkunsigned(L, i);79 r ^= luaL_checkunsigned(L, i);
76 lua_pushunsigned(L, trim(r));80 lua_pushunsigned(L, trim(r));
@@ -79,13 +83,13 @@ static int b_xor (lua_State *L) { · 2 unmodified lines
79 83
80 84
81static int b_not (lua_State *L) {85static int b_not (lua_State *L) {
82 b_uint r = ~luaL_checkunsigned(L, 1);86 lua_Unsigned r = ~luaL_checkunsigned(L, 1);
83 lua_pushunsigned(L, trim(r));87 lua_pushunsigned(L, trim(r));
84 return 1;88 return 1;
85}89}
86 90
87 91
88static int b_shift (lua_State *L, b_uint r, int i) {92static int b_shift (lua_State *L, lua_Unsigned r, int i) {
89 if (i < 0) { /* shift right? */93 if (i < 0) { /* shift right? */
90 i = -i;94 i = -i;
91 r = trim(r);95 r = trim(r);
@@ -113,14 +117,14 @@ static int b_rshift (lua_State *L) { · 21 unmodified lines
113 117
114 118
115static int b_arshift (lua_State *L) {119static int b_arshift (lua_State *L) {
116 b_uint r = luaL_checkunsigned(L, 1);120 lua_Unsigned r = luaL_checkunsigned(L, 1);
117 int i = luaL_checkint(L, 2);121 int i = luaL_checkint(L, 2);
118 if (i < 0 || !(r & ((b_uint)1 << (LUA_NBITS - 1))))122 if (i < 0 || !(r & ((lua_Unsigned)1 << (LUA_NBITS - 1))))
119 return b_shift(L, r, -i);123 return b_shift(L, r, -i);
120 else { /* arithmetic shift for 'negative' number */124 else { /* arithmetic shift for 'negative' number */
121 if (i >= LUA_NBITS) r = ALLONES;125 if (i >= LUA_NBITS) r = ALLONES;
122 else126 else
123 r = trim((r >> i) | ~(trim(~(b_uint)0) >> i)); /* add signal bit */127 r = trim((r >> i) | ~(trim(~(lua_Unsigned)0) >> i)); /* add signal bit */
124 lua_pushunsigned(L, r);128 lua_pushunsigned(L, r);
125 return 1;129 return 1;
126 }130 }
@@ -128,10 +132,11 @@ static int b_arshift (lua_State *L) { · 1 unmodified line
128 132
129 133
130static int b_rot (lua_State *L, int i) {134static int b_rot (lua_State *L, int i) {
131 b_uint r = luaL_checkunsigned(L, 1);135 lua_Unsigned r = luaL_checkunsigned(L, 1);
132 i &= (LUA_NBITS - 1); /* i = i % NBITS */136 i &= (LUA_NBITS - 1); /* i = i % NBITS */
133 r = trim(r);137 r = trim(r);
134 r = (r << i) | (r >> (LUA_NBITS - i));138 if (i != 0) /* avoid undefined shift of LUA_NBITS when i == 0 */
139 r = (r << i) | (r >> (LUA_NBITS - i));
135 lua_pushunsigned(L, trim(r));140 lua_pushunsigned(L, trim(r));
136 return 1;141 return 1;
137}142}
@@ -167,7 +172,7 @@ static int fieldargs (lua_State *L, int farg, int *width) { · 29 unmodified lines
167 172
168static int b_extract (lua_State *L) {173static int b_extract (lua_State *L) {
169 int w;174 int w;
170 b_uint r = trim(luaL_checkunsigned(L, 1));175 lua_Unsigned r = trim(luaL_checkunsigned(L, 1));
171 int f = fieldargs(L, 2, &w);176 int f = fieldargs(L, 2, &w);
172 r = (r >> f) & mask(w);177 r = (r >> f) & mask(w);
173 lua_pushunsigned(L, r);178 lua_pushunsigned(L, r);
@@ -177,8 +182,8 @@ static int b_extract (lua_State *L) { · 3 unmodified lines
177 182
178static int b_replace (lua_State *L) {183static int b_replace (lua_State *L) {
179 int w;184 int w;
180 b_uint r = trim(luaL_checkunsigned(L, 1));185 lua_Unsigned r = trim(luaL_checkunsigned(L, 1));
181 b_uint v = luaL_checkunsigned(L, 2);186 lua_Unsigned v = luaL_checkunsigned(L, 2);
182 int f = fieldargs(L, 3, &w);187 int f = fieldargs(L, 3, &w);
183 int m = mask(w);188 int m = mask(w);
184 v &= m; /* erase bits outside given width */189 v &= m; /* erase bits outside given width */
@@ -211,3 +216,13 @@ LUAMOD_API int luaopen_bit32 (lua_State *L) { · 26 unmodified lines
211 return 1;216 return 1;
212}217}
213 218
219
220#else /* }{ */
221
222
223LUAMOD_API int luaopen_bit32 (lua_State *L) {
224 lua_pushnil(L);
225 return 1;
226}
227
228#endif /* } */
src/lcode.c+65−36
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.c,v 2.71 2013/06/25 18:57:18 roberto Exp $2** $Id: lcode.c,v 2.85 2014/03/21 13:52:33 roberto Exp $
3** Code generator for Lua3** Code generator for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -307,17 +307,21 @@ static void freeexp (FuncState *fs, expdesc *e) { · 301 unmodified lines
307}307}
308 308
309 309
310/*
311** Use scanner's table to cache position of constants in constant list
312** and try to reuse constants
313*/
310static int addk (FuncState *fs, TValue *key, TValue *v) {314static int addk (FuncState *fs, TValue *key, TValue *v) {
311 lua_State *L = fs->ls->L;315 lua_State *L = fs->ls->L;
312 TValue *idx = luaH_set(L, fs->h, key);
313 Proto *f = fs->f;316 Proto *f = fs->f;
317 TValue *idx = luaH_set(L, fs->ls->h, key); /* index scanner table */
314 int k, oldsize;318 int k, oldsize;
315 if (ttisinteger(idx)) {319 if (ttisinteger(idx)) { /* is there an index there? */
316 k = ivalue(idx);320 k = ivalue(idx);
317 if (luaV_rawequalobj(&f->k[k], v))321 /* correct value? (warning: must distinguish floats from integers!) */
318 return k;322 if (k < fs->nk && ttype(&f->k[k]) == ttype(v) &&
319 /* else may be a collision (e.g., between 0.0 and "\0\0\0\0\0\0\0\0");323 luaV_rawequalobj(&f->k[k], v))
320 go through and create a new entry for this value */324 return k; /* reuse index */
321 }325 }
322 /* constant not found; create a new entry */326 /* constant not found; create a new entry */
323 oldsize = f->sizek;327 oldsize = f->sizek;
@@ -360,7 +364,7 @@ int luaK_intK (FuncState *fs, lua_Integer n) { · 36 unmodified lines
360*/ 364*/
361static int luaK_numberK (FuncState *fs, lua_Number r) {365static int luaK_numberK (FuncState *fs, lua_Number r) {
362 TValue o;366 TValue o;
363 lua_assert(!luai_numisnan(NULL, r) && !isminuszero(r));367 lua_assert(!luai_numisnan(r) && !isminuszero(r));
364 setnvalue(&o, r);368 setnvalue(&o, r);
365 return addk(fs, &o, &o);369 return addk(fs, &o, &o);
366}370}
@@ -377,7 +381,7 @@ static int nilK (FuncState *fs) { · 10 unmodified lines
377 TValue k, v;381 TValue k, v;
378 setnilvalue(&v);382 setnilvalue(&v);
379 /* cannot use nil as key; instead use table itself to represent nil */383 /* cannot use nil as key; instead use table itself to represent nil */
380 sethvalue(fs->ls->L, &k, fs->h);384 sethvalue(fs->ls->L, &k, fs->ls->h);
381 return addk(fs, &k, &v);385 return addk(fs, &k, &v);
382}386}
383 387
@@ -746,24 +750,46 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) { · 362 unmodified lines
746}750}
747 751
748 752
749static int constfolding (OpCode op, expdesc *e1, expdesc *e2) {753/*
750 TValue v1, v2, res;754** return false if folding can raise an error
755*/
756static int validop (int op, TValue *v1, TValue *v2) {
757 lua_Number a, b;
751 lua_Integer i;758 lua_Integer i;
752 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2))759 cast_void(a); cast_void(b); /* macro may not use its arguments */
760 if (luai_numinvalidop(op, (cast_void(tonumber(v1, &a)), a),
761 (cast_void(tonumber(v2, &b)), b)))
753 return 0;762 return 0;
754 if (op == OP_IDIV &&763 switch (op) {
755 (!tointeger(&v1, &i) || !tointeger(&v2, &i) || i == 0))764 case LUA_OPIDIV: /* division by 0 and conversion errors */
756 return 0; /* avoid division by 0 and conversion errors */765 return (tointeger(v1, &i) && tointeger(v2, &i) && i != 0);
757 if (op == OP_MOD && ttisinteger(&v1) && ttisinteger(&v2) && ivalue(&v2) == 0)766 case LUA_OPBAND: case LUA_OPBOR: case LUA_OPBXOR:
758 return 0; /* avoid module by 0 at compile time */767 case LUA_OPSHL: case LUA_OPSHR: case LUA_OPBNOT: /* conversion errors */
759 luaO_arith(NULL, op - OP_ADD + LUA_OPADD, &v1, &v2, &res);768 return (tointeger(v1, &i) && tointeger(v2, &i));
769 case LUA_OPMOD: /* integer module by 0 */
770 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) == 0);
771 case LUA_OPPOW: /* negative integer exponentiation */
772 return !(ttisinteger(v1) && ttisinteger(v2) && ivalue(v2) < 0);
773 default: return 1; /* everything else is valid */
774 }
775}
776
777
778/*
779** Try to "constant-fold" an operation; return 1 iff successful
780*/
781static int constfolding (FuncState *fs, int op, expdesc *e1, expdesc *e2) {
782 TValue v1, v2, res;
783 if (!tonumeral(e1, &v1) || !tonumeral(e2, &v2) || !validop(op, &v1, &v2))
784 return 0; /* non-numeric operands or not safe to fold */
785 luaO_arith(fs->ls->L, op, &v1, &v2, &res);
760 if (ttisinteger(&res)) {786 if (ttisinteger(&res)) {
761 e1->k = VKINT;787 e1->k = VKINT;
762 e1->u.ival = ivalue(&res);788 e1->u.ival = ivalue(&res);
763 }789 }
764 else {790 else {
765 lua_Number n = fltvalue(&res);791 lua_Number n = fltvalue(&res);
766 if (luai_numisnan(NULL, n) || isminuszero(n))792 if (luai_numisnan(n) || isminuszero(n))
767 return 0; /* folds neither NaN nor -0 */793 return 0; /* folds neither NaN nor -0 */
768 e1->k = VKFLT;794 e1->k = VKFLT;
769 e1->u.nval = n;795 e1->u.nval = n;
@@ -774,9 +800,16 @@ static int constfolding (OpCode op, expdesc *e1, expdesc *e2) { · 4 unmodified lines
774 800
775static void codearith (FuncState *fs, OpCode op,801static void codearith (FuncState *fs, OpCode op,
776 expdesc *e1, expdesc *e2, int line) {802 expdesc *e1, expdesc *e2, int line) {
777 if (!constfolding(op, e1, e2)) { /* could not fold operation? */803 if (!constfolding(fs, op - OP_ADD + LUA_OPADD, e1, e2)) {
778 int o2 = (op != OP_UNM && op != OP_LEN) ? luaK_exp2RK(fs, e2) : 0;804 int o1, o2;
779 int o1 = luaK_exp2RK(fs, e1);805 if (op == OP_UNM || op == OP_BNOT || op == OP_LEN) {
806 o2 = 0;
807 o1 = luaK_exp2anyreg(fs, e1); /* cannot operate on constants */
808 }
809 else { /* regular case (binary operators) */
810 o2 = luaK_exp2RK(fs, e2);
811 o1 = luaK_exp2RK(fs, e1);
812 }
780 if (o1 > o2) {813 if (o1 > o2) {
781 freeexp(fs, e1);814 freeexp(fs, e1);
782 freeexp(fs, e2);815 freeexp(fs, e2);
@@ -810,21 +843,13 @@ static void codecomp (FuncState *fs, OpCode op, int cond, expdesc *e1, · 27 unmodified lines
810 843
811void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {844void luaK_prefix (FuncState *fs, UnOpr op, expdesc *e, int line) {
812 expdesc e2;845 expdesc e2;
813 e2.t = e2.f = NO_JUMP; e2.k = VKFLT; e2.u.nval = 0;846 e2.t = e2.f = NO_JUMP; e2.k = VKINT; e2.u.ival = 0;
814 switch (op) {847 switch (op) {
815 case OPR_MINUS: {848 case OPR_MINUS: case OPR_BNOT: case OPR_LEN: {
816 if (!constfolding(OP_UNM, e, e)) { /* cannot fold it? */849 codearith(fs, cast(OpCode, (op - OPR_MINUS) + OP_UNM), e, &e2, line);
817 luaK_exp2anyreg(fs, e);
818 codearith(fs, OP_UNM, e, &e2, line);
819 }
820 break;850 break;
821 }851 }
822 case OPR_NOT: codenot(fs, e); break;852 case OPR_NOT: codenot(fs, e); break;
823 case OPR_LEN: {
824 luaK_exp2anyreg(fs, e); /* cannot operate on constants */
825 codearith(fs, OP_LEN, e, &e2, line);
826 break;
827 }
828 default: lua_assert(0);853 default: lua_assert(0);
829 }854 }
830}855}
@@ -846,7 +871,9 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) { · 15 unmodified lines
846 }871 }
847 case OPR_ADD: case OPR_SUB:872 case OPR_ADD: case OPR_SUB:
848 case OPR_MUL: case OPR_DIV: case OPR_IDIV:873 case OPR_MUL: case OPR_DIV: case OPR_IDIV:
849 case OPR_MOD: case OPR_POW: {874 case OPR_MOD: case OPR_POW:
875 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
876 case OPR_SHL: case OPR_SHR: {
850 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);877 if (!tonumeral(v, NULL)) luaK_exp2RK(fs, v);
851 break;878 break;
852 }879 }
@@ -890,8 +917,10 @@ void luaK_posfix (FuncState *fs, BinOpr op, · 37 unmodified lines
890 break;917 break;
891 }918 }
892 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:919 case OPR_ADD: case OPR_SUB: case OPR_MUL: case OPR_DIV:
893 case OPR_IDIV: case OPR_MOD: case OPR_POW: {920 case OPR_IDIV: case OPR_MOD: case OPR_POW:
894 codearith(fs, cast(OpCode, op - OPR_ADD + OP_ADD), e1, e2, line);921 case OPR_BAND: case OPR_BOR: case OPR_BXOR:
922 case OPR_SHL: case OPR_SHR: {
923 codearith(fs, cast(OpCode, (op - OPR_ADD) + OP_ADD), e1, e2, line);
895 break;924 break;
896 }925 }
897 case OPR_EQ: case OPR_LT: case OPR_LE: {926 case OPR_EQ: case OPR_LT: case OPR_LE: {
src/lcode.h+7−3
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lcode.h,v 1.60 2013/04/26 13:07:53 roberto Exp $2** $Id: lcode.h,v 1.63 2013/12/30 20:47:58 roberto Exp $
3** Code generator for Lua3** Code generator for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -24,7 +24,11 @@ · 18 unmodified lines
24** grep "ORDER OPR" if you change these enums (ORDER OP)24** grep "ORDER OPR" if you change these enums (ORDER OP)
25*/25*/
26typedef enum BinOpr {26typedef enum BinOpr {
27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_DIV, OPR_IDIV, OPR_MOD, OPR_POW,27 OPR_ADD, OPR_SUB, OPR_MUL, OPR_MOD, OPR_POW,
28 OPR_DIV,
29 OPR_IDIV,
30 OPR_BAND, OPR_BOR, OPR_BXOR,
31 OPR_SHL, OPR_SHR,
28 OPR_CONCAT,32 OPR_CONCAT,
29 OPR_EQ, OPR_LT, OPR_LE,33 OPR_EQ, OPR_LT, OPR_LE,
30 OPR_NE, OPR_GT, OPR_GE,34 OPR_NE, OPR_GT, OPR_GE,
@@ -33,7 +37,7 @@ typedef enum BinOpr { · 2 unmodified lines
33} BinOpr;37} BinOpr;
34 38
35 39
36typedef enum UnOpr { OPR_MINUS, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;40typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
37 41
38 42
39#define getcode(fs,e) ((fs)->f->code[(e)->u.info])43#define getcode(fs,e) ((fs)->f->code[(e)->u.info])
src/ldblib.c+3−7
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldblib.c,v 1.133 2013/06/25 19:37:00 roberto Exp $2** $Id: ldblib.c,v 1.137 2014/03/12 20:57:40 roberto Exp $
3** Interface from Lua to its debug API3** Interface from Lua to its debug API
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -69,11 +69,8 @@ static int db_getuservalue (lua_State *L) { · 63 unmodified lines
69 69
70 70
71static int db_setuservalue (lua_State *L) {71static int db_setuservalue (lua_State *L) {
72 if (lua_type(L, 1) == LUA_TLIGHTUSERDATA)
73 luaL_argerror(L, 1, "full userdata expected, got light userdata");
74 luaL_checktype(L, 1, LUA_TUSERDATA);72 luaL_checktype(L, 1, LUA_TUSERDATA);
75 if (!lua_isnoneornil(L, 2))73 luaL_checkany(L, 2);
76 luaL_checktype(L, 2, LUA_TTABLE);
77 lua_settop(L, 2);74 lua_settop(L, 2);
78 lua_setuservalue(L, 1);75 lua_setuservalue(L, 1);
79 return 1;76 return 1;
@@ -273,8 +270,7 @@ static void hookf (lua_State *L, lua_Debug *ar) { · 193 unmodified lines
273 {"call", "return", "line", "count", "tail call"};270 {"call", "return", "line", "count", "tail call"};
274 gethooktable(L);271 gethooktable(L);
275 lua_pushthread(L);272 lua_pushthread(L);
276 lua_rawget(L, -2);273 if (lua_rawget(L, -2) == LUA_TFUNCTION) {
277 if (lua_isfunction(L, -1)) {
278 lua_pushstring(L, hooknames[(int)ar->event]);274 lua_pushstring(L, hooknames[(int)ar->event]);
279 if (ar->currentline >= 0)275 if (ar->currentline >= 0)
280 lua_pushinteger(L, ar->currentline);276 lua_pushinteger(L, ar->currentline);
src/ldebug.c+20−13
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldebug.c,v 2.95 2013/05/06 17:21:59 roberto Exp $2** $Id: ldebug.c,v 2.97 2013/12/09 14:21:10 roberto Exp $
3** Debug Interface3** Debug Interface
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -50,7 +50,7 @@ static int currentline (CallInfo *ci) { · 44 unmodified lines
50/*50/*
51** this function can be called asynchronous (e.g. during a signal)51** this function can be called asynchronous (e.g. during a signal)
52*/52*/
53LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {53LUA_API void lua_sethook (lua_State *L, lua_Hook func, int mask, int count) {
54 if (func == NULL || mask == 0) { /* turn off hooks? */54 if (func == NULL || mask == 0) { /* turn off hooks? */
55 mask = 0;55 mask = 0;
56 func = NULL;56 func = NULL;
@@ -61,7 +61,6 @@ LUA_API int lua_sethook (lua_State *L, lua_Hook func, int mask, int count) { · 4 unmodified lines
61 L->basehookcount = count;61 L->basehookcount = count;
62 resethookcount(L);62 resethookcount(L);
63 L->hookmask = cast_byte(mask);63 L->hookmask = cast_byte(mask);
64 return 1;
65}64}
66 65
67 66
@@ -327,12 +326,20 @@ static void kname (Proto *p, int pc, int c, const char **name) { · 259 unmodified lines
327}326}
328 327
329 328
329static int filterpc (int pc, int jmptarget) {
330 if (pc < jmptarget) /* is code conditional (inside a jump)? */
331 return -1; /* cannot know who sets that register */
332 else return pc; /* current position sets that register */
333}
334
335
330/*336/*
331** try to find last instruction before 'lastpc' that modified register 'reg'337** try to find last instruction before 'lastpc' that modified register 'reg'
332*/338*/
333static int findsetreg (Proto *p, int lastpc, int reg) {339static int findsetreg (Proto *p, int lastpc, int reg) {
334 int pc;340 int pc;
335 int setreg = -1; /* keep last instruction that changed 'reg' */341 int setreg = -1; /* keep last instruction that changed 'reg' */
342 int jmptarget = 0; /* any code before this address is conditional */
336 for (pc = 0; pc < lastpc; pc++) {343 for (pc = 0; pc < lastpc; pc++) {
337 Instruction i = p->code[pc];344 Instruction i = p->code[pc];
338 OpCode op = GET_OPCODE(i);345 OpCode op = GET_OPCODE(i);
@@ -341,33 +348,33 @@ static int findsetreg (Proto *p, int lastpc, int reg) { · 2 unmodified lines
341 case OP_LOADNIL: {348 case OP_LOADNIL: {
342 int b = GETARG_B(i);349 int b = GETARG_B(i);
343 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */350 if (a <= reg && reg <= a + b) /* set registers from 'a' to 'a+b' */
344 setreg = pc;351 setreg = filterpc(pc, jmptarget);
345 break;352 break;
346 }353 }
347 case OP_TFORCALL: {354 case OP_TFORCALL: {
348 if (reg >= a + 2) setreg = pc; /* affect all regs above its base */355 if (reg >= a + 2) /* affect all regs above its base */
356 setreg = filterpc(pc, jmptarget);
349 break;357 break;
350 }358 }
351 case OP_CALL:359 case OP_CALL:
352 case OP_TAILCALL: {360 case OP_TAILCALL: {
353 if (reg >= a) setreg = pc; /* affect all registers above base */361 if (reg >= a) /* affect all registers above base */
362 setreg = filterpc(pc, jmptarget);
354 break;363 break;
355 }364 }
356 case OP_JMP: {365 case OP_JMP: {
357 int b = GETARG_sBx(i);366 int b = GETARG_sBx(i);
358 int dest = pc + 1 + b;367 int dest = pc + 1 + b;
359 /* jump is forward and do not skip `lastpc'? */368 /* jump is forward and do not skip `lastpc'? */
360 if (pc < dest && dest <= lastpc)369 if (pc < dest && dest <= lastpc) {
361 pc += b; /* do the jump */370 if (dest > jmptarget)
362 break;371 jmptarget = dest; /* update 'jmptarget' */
363 }372 }
364 case OP_TEST: {
365 if (reg == a) setreg = pc; /* jumped code can change 'a' */
366 break;373 break;
367 }374 }
368 default:375 default:
369 if (testAMode(op) && reg == a) /* any instruction that set A */376 if (testAMode(op) && reg == a) /* any instruction that set A */
370 setreg = pc;377 setreg = filterpc(pc, jmptarget);
371 break;378 break;
372 }379 }
373 }380 }
src/ldebug.h+2−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldebug.h,v 2.10 2013/05/06 17:19:11 roberto Exp $2** $Id: ldebug.h,v 2.11 2014/02/25 14:31:16 roberto Exp $
3** Auxiliary functions from Debug Interface module3** Auxiliary functions from Debug Interface module
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -13,7 +13,7 @@ · 7 unmodified lines
13 13
14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)14#define pcRel(pc, p) (cast(int, (pc) - (p)->code) - 1)
15 15
16#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : 0)16#define getfuncline(f,pc) (((f)->lineinfo) ? (f)->lineinfo[pc] : -1)
17 17
18#define resethookcount(L) (L->hookcount = L->basehookcount)18#define resethookcount(L) (L->hookcount = L->basehookcount)
19 19
src/ldo.c+23−20
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldo.c,v 2.109 2013/04/19 21:05:04 roberto Exp $2** $Id: ldo.c,v 2.115 2014/03/21 13:52:33 roberto Exp $
3** Stack and Call structure of Lua3** Stack and Call structure of Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -46,30 +46,33 @@ · 40 unmodified lines
46** C++ code, with _longjmp/_setjmp when asked to use them, and with46** C++ code, with _longjmp/_setjmp when asked to use them, and with
47** longjmp/setjmp otherwise.47** longjmp/setjmp otherwise.
48*/48*/
49#if !defined(LUAI_THROW)49#if !defined(LUAI_THROW) /* { */
50
51#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP) /* { */
50 52
51#if defined(__cplusplus) && !defined(LUA_USE_LONGJMP)
52/* C++ exceptions */53/* C++ exceptions */
53#define LUAI_THROW(L,c) throw(c)54#define LUAI_THROW(L,c) throw(c)
54#define LUAI_TRY(L,c,a) \55#define LUAI_TRY(L,c,a) \
55 try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }56 try { a } catch(...) { if ((c)->status == 0) (c)->status = -1; }
56#define luai_jmpbuf int /* dummy variable */57#define luai_jmpbuf int /* dummy variable */
57 58
58#elif defined(LUA_USE_ULONGJMP)59#elif defined(LUA_USE_POSIX) /* }{ */
59/* in Unix, try _longjmp/_setjmp (more efficient) */60
61/* in POSIX, try _longjmp/_setjmp (more efficient) */
60#define LUAI_THROW(L,c) _longjmp((c)->b, 1)62#define LUAI_THROW(L,c) _longjmp((c)->b, 1)
61#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }63#define LUAI_TRY(L,c,a) if (_setjmp((c)->b) == 0) { a }
62#define luai_jmpbuf jmp_buf64#define luai_jmpbuf jmp_buf
63 65
64#else66#else /* }{ */
65/* default handling with long jumps */67
68/* ANSI handling with long jumps */
66#define LUAI_THROW(L,c) longjmp((c)->b, 1)69#define LUAI_THROW(L,c) longjmp((c)->b, 1)
67#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }70#define LUAI_TRY(L,c,a) if (setjmp((c)->b) == 0) { a }
68#define luai_jmpbuf jmp_buf71#define luai_jmpbuf jmp_buf
69 72
70#endif73#endif /* } */
71 74
72#endif75#endif /* } */
73 76
74 77
75 78
@@ -141,10 +144,10 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { · 65 unmodified lines
141 144
142static void correctstack (lua_State *L, TValue *oldstack) {145static void correctstack (lua_State *L, TValue *oldstack) {
143 CallInfo *ci;146 CallInfo *ci;
144 GCObject *up;147 UpVal *up;
145 L->top = (L->top - oldstack) + L->stack;148 L->top = (L->top - oldstack) + L->stack;
146 for (up = L->openupval; up != NULL; up = up->gch.next)149 for (up = L->openupval; up != NULL; up = up->u.open.next)
147 gco2uv(up)->v = (gco2uv(up)->v - oldstack) + L->stack;150 up->v = (up->v - oldstack) + L->stack;
148 for (ci = L->ci; ci != NULL; ci = ci->previous) {151 for (ci = L->ci; ci != NULL; ci = ci->previous) {
149 ci->top = (ci->top - oldstack) + L->stack;152 ci->top = (ci->top - oldstack) + L->stack;
150 ci->func = (ci->func - oldstack) + L->stack;153 ci->func = (ci->func - oldstack) + L->stack;
@@ -206,7 +209,11 @@ void luaD_shrinkstack (lua_State *L) { · 55 unmodified lines
206 int inuse = stackinuse(L);209 int inuse = stackinuse(L);
207 int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;210 int goodsize = inuse + (inuse / 8) + 2*EXTRA_STACK;
208 if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;211 if (goodsize > LUAI_MAXSTACK) goodsize = LUAI_MAXSTACK;
209 if (inuse > LUAI_MAXSTACK || /* handling stack overflow? */212 if (L->stacksize > LUAI_MAXSTACK) /* was handling stack overflow? */
213 luaE_freeCI(L); /* free all CIs (list grew because of an error) */
214 else
215 luaE_shrinkCI(L); /* shrink list */
216 if (inuse > LUAI_MAXSTACK || /* still handling stack overflow? */
210 goodsize >= L->stacksize) /* would grow instead of shrink? */217 goodsize >= L->stacksize) /* would grow instead of shrink? */
211 condmovestack(L); /* don't change stack (change only for debugging) */218 condmovestack(L); /* don't change stack (change only for debugging) */
212 else219 else
@@ -534,6 +541,7 @@ static void resume (lua_State *L, void *ud) { · 321 unmodified lines
534 541
535LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {542LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) {
536 int status;543 int status;
544 int oldnny = L->nny; /* save 'nny' */
537 lua_lock(L);545 lua_lock(L);
538 luai_userstateresume(L, nargs);546 luai_userstateresume(L, nargs);
539 L->nCcalls = (from) ? from->nCcalls + 1 : 1;547 L->nCcalls = (from) ? from->nCcalls + 1 : 1;
@@ -555,7 +563,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs) { · 15 unmodified lines
555 }563 }
556 lua_assert(status == L->status);564 lua_assert(status == L->status);
557 }565 }
558 L->nny = 1; /* do not allow yields */566 L->nny = oldnny; /* restore 'nny' */
559 L->nCcalls--;567 L->nCcalls--;
560 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));568 lua_assert(L->nCcalls == ((from) ? from->nCcalls : 0));
561 lua_unlock(L);569 lua_unlock(L);
@@ -637,7 +645,6 @@ static void checkmode (lua_State *L, const char *mode, const char *x) { · 75 unmodified lines
637 645
638 646
639static void f_parser (lua_State *L, void *ud) {647static void f_parser (lua_State *L, void *ud) {
640 int i;
641 Closure *cl;648 Closure *cl;
642 struct SParser *p = cast(struct SParser *, ud);649 struct SParser *p = cast(struct SParser *, ud);
643 int c = zgetc(p->z); /* read first character */650 int c = zgetc(p->z); /* read first character */
@@ -650,11 +657,7 @@ static void f_parser (lua_State *L, void *ud) { · 6 unmodified lines
650 cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);657 cl = luaY_parser(L, p->z, &p->buff, &p->dyd, p->name, c);
651 }658 }
652 lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);659 lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
653 for (i = 0; i < cl->l.nupvalues; i++) { /* initialize upvalues */660 luaF_initupvals(L, &cl->l);
654 UpVal *up = luaF_newupval(L);
655 cl->l.upvals[i] = up;
656 luaC_objbarrier(L, cl, up);
657 }
658}661}
659 662
660 663
src/ldump.c+154−133
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ldump.c,v 2.19 2013/04/26 18:48:35 roberto Exp $2** $Id: ldump.c,v 2.27 2014/03/11 18:56:27 roberto Exp $
3** save precompiled Lua chunks3** save precompiled Lua chunks
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -15,167 +15,188 @@ · 9 unmodified lines
15#include "lstate.h"15#include "lstate.h"
16#include "lundump.h"16#include "lundump.h"
17 17
18
18typedef struct {19typedef struct {
19 lua_State* L;20 lua_State *L;
20 lua_Writer writer;21 lua_Writer writer;
21 void* data;22 void *data;
22 int strip;23 int strip;
23 int status;24 int status;
24} DumpState;25} DumpState;
25 26
26#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)27
27#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)28/*
28 29** All high-level dumps go through DumpVector; you can change it to
29static void DumpBlock(const void* b, size_t size, DumpState* D)30** change the endianess of the result
30{31*/
31 if (D->status==0)32#define DumpVector(v,n,D) DumpBlock(v,(n)*sizeof((v)[0]),D)
32 {33
33 lua_unlock(D->L);34#define DumpLiteral(s,D) DumpBlock(s, sizeof(s) - sizeof(char), D)
34 D->status=(*D->writer)(D->L,b,size,D->data);35
35 lua_lock(D->L);36
36 }37static void DumpBlock (const void *b, size_t size, DumpState *D) {
38 if (D->status == 0) {
39 lua_unlock(D->L);
40 D->status = (*D->writer)(D->L, b, size, D->data);
41 lua_lock(D->L);
42 }
37}43}
38 44
39static void DumpChar(int y, DumpState* D)45
40{46#define DumpVar(x,D) DumpVector(&x,1,D)
41 char x=(char)y;47
42 DumpVar(x,D);48
49static void DumpByte (int y, DumpState *D) {
50 lu_byte x = (lu_byte)y;
51 DumpVar(x, D);
43}52}
44 53
45static void DumpInt(int x, DumpState* D)54
46{55static void DumpInt (int x, DumpState *D) {
47 DumpVar(x,D);56 DumpVar(x, D);
48}57}
49 58
50static void DumpNumber(lua_Number x, DumpState* D)59
51{60static void DumpNumber (lua_Number x, DumpState *D) {
52 DumpVar(x,D);61 DumpVar(x, D);
53}62}
54 63
55static void DumpInteger(lua_Integer x, DumpState* D)64
56{65static void DumpInteger (lua_Integer x, DumpState *D) {
57 DumpVar(x,D);66 DumpVar(x, D);
58}67}
59 68
60static void DumpVector(const void* b, int n, size_t size, DumpState* D)69
61{70static void DumpString (const TString *s, DumpState *D) {
62 DumpInt(n,D);71 if (s == NULL)
63 DumpMem(b,n,size,D);72 DumpByte(0, D);
73 else {
74 size_t size = s->tsv.len + 1; /* include trailing '\0' */
75 if (size < 0xFF)
76 DumpByte(size, D);
77 else {
78 DumpByte(0xFF, D);
79 DumpVar(size, D);
80 }
81 DumpVector(getstr(s), size - 1, D); /* no need to save '\0' */
82 }
64}83}
65 84
66static void DumpString(const TString* s, DumpState* D)85
67{86static void DumpCode (const Proto *f, DumpState *D) {
68 if (s==NULL)87 DumpInt(f->sizecode, D);
69 {88 DumpVector(f->code, f->sizecode, D);
70 size_t size=0;
71 DumpVar(size,D);
72 }
73 else
74 {
75 size_t size=s->tsv.len+1; /* include trailing '\0' */
76 DumpVar(size,D);
77 DumpBlock(getstr(s),size*sizeof(char),D);
78 }
79}89}
80 90
81#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)91
82 92static void DumpFunction(const Proto *f, DumpState *D);
83static void DumpFunction(const Proto* f, DumpState* D);93
84 94static void DumpConstants (const Proto *f, DumpState *D) {
85static void DumpConstants(const Proto* f, DumpState* D)95 int i;
86{96 int n = f->sizek;
87 int i,n=f->sizek;97 DumpInt(n, D);
88 DumpInt(n,D);98 for (i = 0; i < n; i++) {
89 for (i=0; i<n; i++)99 const TValue *o = &f->k[i];
90 {100 DumpByte(ttype(o), D);
91 const TValue* o=&f->k[i];101 switch (ttype(o)) {
92 DumpChar(ttype(o),D);102 case LUA_TNIL:
93 switch (ttype(o))103 break;
94 {104 case LUA_TBOOLEAN:
95 case LUA_TNIL:105 DumpByte(bvalue(o), D);
96 break;106 break;
97 case LUA_TBOOLEAN:107 case LUA_TNUMFLT:
98 DumpChar(bvalue(o),D);108 DumpNumber(fltvalue(o), D);
99 break;109 break;
100 case LUA_TNUMFLT:110 case LUA_TNUMINT:
101 DumpNumber(fltvalue(o),D);111 DumpInteger(ivalue(o), D);
102 break;112 break;
103 case LUA_TNUMINT:113 case LUA_TSHRSTR:
104 DumpInteger(ivalue(o),D);114 case LUA_TLNGSTR:
105 break;115 DumpString(rawtsvalue(o), D);
106 case LUA_TSHRSTR: case LUA_TLNGSTR:116 break;
107 DumpString(rawtsvalue(o),D);117 default:
108 break;118 lua_assert(0);
109 default: lua_assert(0);119 }
110 }120 }
111 }121 n = f->sizep;
112 n=f->sizep;122 DumpInt(n, D);
113 DumpInt(n,D);123 for (i = 0; i < n; i++)
114 for (i=0; i<n; i++) DumpFunction(f->p[i],D);124 DumpFunction(f->p[i], D);
115}125}
116 126
117static void DumpUpvalues(const Proto* f, DumpState* D)127
118{128static void DumpUpvalues (const Proto *f, DumpState *D) {
119 int i,n=f->sizeupvalues;129 int i, n = f->sizeupvalues;
120 DumpInt(n,D);130 DumpInt(n, D);
121 for (i=0; i<n; i++)131 for (i = 0; i < n; i++) {
122 {132 DumpByte(f->upvalues[i].instack, D);
123 DumpChar(f->upvalues[i].instack,D);133 DumpByte(f->upvalues[i].idx, D);
124 DumpChar(f->upvalues[i].idx,D);134 }
125 }
126}135}
127 136
128static void DumpDebug(const Proto* f, DumpState* D)137
129{138static void DumpDebug (const Proto *f, DumpState *D) {
130 int i,n;139 int i, n;
131 DumpString((D->strip) ? NULL : f->source,D);140 DumpString((D->strip) ? NULL : f->source, D);
132 n= (D->strip) ? 0 : f->sizelineinfo;141 n = (D->strip) ? 0 : f->sizelineinfo;
133 DumpVector(f->lineinfo,n,sizeof(int),D);142 DumpInt(n, D);
134 n= (D->strip) ? 0 : f->sizelocvars;143 DumpVector(f->lineinfo, n, D);
135 DumpInt(n,D);144 n = (D->strip) ? 0 : f->sizelocvars;
136 for (i=0; i<n; i++)145 DumpInt(n, D);
137 {146 for (i = 0; i < n; i++) {
138 DumpString(f->locvars[i].varname,D);147 DumpString(f->locvars[i].varname, D);
139 DumpInt(f->locvars[i].startpc,D);148 DumpInt(f->locvars[i].startpc, D);
140 DumpInt(f->locvars[i].endpc,D);149 DumpInt(f->locvars[i].endpc, D);
141 }150 }
142 n= (D->strip) ? 0 : f->sizeupvalues;151 n = (D->strip) ? 0 : f->sizeupvalues;
143 DumpInt(n,D);152 DumpInt(n, D);
144 for (i=0; i<n; i++) DumpString(f->upvalues[i].name,D);153 for (i = 0; i < n; i++)
154 DumpString(f->upvalues[i].name, D);
145}155}
146 156
147static void DumpFunction(const Proto* f, DumpState* D)157
148{158static void DumpFunction (const Proto *f, DumpState *D) {
149 DumpInt(f->linedefined,D);159 DumpInt(f->linedefined, D);
150 DumpInt(f->lastlinedefined,D);160 DumpInt(f->lastlinedefined, D);
151 DumpChar(f->numparams,D);161 DumpByte(f->numparams, D);
152 DumpChar(f->is_vararg,D);162 DumpByte(f->is_vararg, D);
153 DumpChar(f->maxstacksize,D);163 DumpByte(f->maxstacksize, D);
154 DumpCode(f,D);164 DumpCode(f, D);
155 DumpConstants(f,D);165 DumpConstants(f, D);
156 DumpUpvalues(f,D);166 DumpUpvalues(f, D);
157 DumpDebug(f,D);167 DumpDebug(f, D);
158}168}
159 169
160static void DumpHeader(DumpState* D)170
161{171static void DumpHeader (DumpState *D) {
162 lu_byte h[LUAC_HEADERSIZE];172 DumpLiteral(LUA_SIGNATURE, D);
163 luaU_header(h);173 DumpByte(LUAC_VERSION, D);
164 DumpBlock(h,LUAC_HEADERSIZE,D);174 DumpByte(LUAC_FORMAT, D);
175 DumpLiteral(LUAC_DATA, D);
176 DumpByte(sizeof(int), D);
177 DumpByte(sizeof(size_t), D);
178 DumpByte(sizeof(Instruction), D);
179 DumpByte(sizeof(lua_Integer), D);
180 DumpByte(sizeof(lua_Number), D);
181 DumpInteger(LUAC_INT, D);
182 DumpNumber(LUAC_NUM, D);
165}183}
166 184
185
167/*186/*
168** dump Lua function as precompiled chunk187** dump Lua function as precompiled chunk
169*/188*/
170int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)189int luaU_dump(lua_State *L, const Proto *f, lua_Writer w, void *data,
171{190 int strip) {
172 DumpState D;191 DumpState D;
173 D.L=L;192 D.L = L;
174 D.writer=w;193 D.writer = w;
175 D.data=data;194 D.data = data;
176 D.strip=strip;195 D.strip = strip;
177 D.status=0;196 D.status = 0;
178 DumpHeader(&D);197 DumpHeader(&D);
179 DumpFunction(f,&D);198 DumpByte(f->sizeupvalues, &D);
180 return D.status;199 DumpFunction(f, &D);
200 return D.status;
181}201}
202
src/lfunc.c+39−54
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lfunc.c,v 2.30 2012/10/03 12:36:46 roberto Exp $2** $Id: lfunc.c,v 2.41 2014/02/18 13:39:37 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -21,94 +21,79 @@ · 15 unmodified lines
21 21
22 22
23Closure *luaF_newCclosure (lua_State *L, int n) {23Closure *luaF_newCclosure (lua_State *L, int n) {
24 Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n), NULL, 0)->cl;24 Closure *c = &luaC_newobj(L, LUA_TCCL, sizeCclosure(n))->cl;
25 c->c.nupvalues = cast_byte(n);25 c->c.nupvalues = cast_byte(n);
26 return c;26 return c;
27}27}
28 28
29 29
30Closure *luaF_newLclosure (lua_State *L, int n) {30Closure *luaF_newLclosure (lua_State *L, int n) {
31 Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n), NULL, 0)->cl;31 Closure *c = &luaC_newobj(L, LUA_TLCL, sizeLclosure(n))->cl;
32 c->l.p = NULL;32 c->l.p = NULL;
33 c->l.nupvalues = cast_byte(n);33 c->l.nupvalues = cast_byte(n);
34 while (n--) c->l.upvals[n] = NULL;34 while (n--) c->l.upvals[n] = NULL;
35 return c;35 return c;
36}36}
37 37
38 38/*
39UpVal *luaF_newupval (lua_State *L) {39** fill a closure with new closed upvalues
40 UpVal *uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), NULL, 0)->uv;40*/
41 uv->v = &uv->u.value;41void luaF_initupvals (lua_State *L, LClosure *cl) {
42 setnilvalue(uv->v);42 int i;
43 return uv;43 for (i = 0; i < cl->nupvalues; i++) {
44 UpVal *uv = luaM_new(L, UpVal);
45 uv->refcount = 1;
46 uv->v = &uv->u.value; /* make it closed */
47 setnilvalue(uv->v);
48 cl->upvals[i] = uv;
49 }
44}50}
45 51
46 52
47UpVal *luaF_findupval (lua_State *L, StkId level) {53UpVal *luaF_findupval (lua_State *L, StkId level) {
48 global_State *g = G(L);54 UpVal **pp = &L->openupval;
49 GCObject **pp = &L->openupval;
50 UpVal *p;55 UpVal *p;
51 UpVal *uv;56 UpVal *uv;
52 while (*pp != NULL && (p = gco2uv(*pp))->v >= level) {57 lua_assert(isintwups(L) || L->openupval == NULL);
53 GCObject *o = obj2gco(p);58 while (*pp != NULL && (p = *pp)->v >= level) {
54 lua_assert(p->v != &p->u.value);59 lua_assert(upisopen(p));
55 lua_assert(!isold(o) || isold(obj2gco(L)));60 if (p->v == level) /* found a corresponding upvalue? */
56 if (p->v == level) { /* found a corresponding upvalue? */61 return p; /* return it */
57 if (isdead(g, o)) /* is it dead? */62 pp = &p->u.open.next;
58 changewhite(o); /* resurrect it */
59 return p;
60 }
61 pp = &p->next;
62 }63 }
63 /* not found: create a new one */64 /* not found: create a new upvalue */
64 uv = &luaC_newobj(L, LUA_TUPVAL, sizeof(UpVal), pp, 0)->uv;65 uv = luaM_new(L, UpVal);
66 uv->refcount = 0;
67 uv->u.open.next = *pp; /* link it to list of open upvalues */
68 uv->u.open.touched = 1;
69 *pp = uv;
65 uv->v = level; /* current value lives in the stack */70 uv->v = level; /* current value lives in the stack */
66 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */71 if (!isintwups(L)) { /* thread not in list of threads with upvalues? */
67 uv->u.l.next = g->uvhead.u.l.next;72 L->twups = G(L)->twups; /* link it to the list */
68 uv->u.l.next->u.l.prev = uv;73 G(L)->twups = L;
69 g->uvhead.u.l.next = uv;74 }
70 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
71 return uv;75 return uv;
72}76}
73 77
74 78
75static void unlinkupval (UpVal *uv) {
76 lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv);
77 uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */
78 uv->u.l.prev->u.l.next = uv->u.l.next;
79}
80
81
82void luaF_freeupval (lua_State *L, UpVal *uv) {
83 if (uv->v != &uv->u.value) /* is it open? */
84 unlinkupval(uv); /* remove from open list */
85 luaM_free(L, uv); /* free upvalue */
86}
87
88
89void luaF_close (lua_State *L, StkId level) {79void luaF_close (lua_State *L, StkId level) {
90 UpVal *uv;80 UpVal *uv;
91 global_State *g = G(L);81 while (L->openupval != NULL && (uv = L->openupval)->v >= level) {
92 while (L->openupval != NULL && (uv = gco2uv(L->openupval))->v >= level) {82 lua_assert(upisopen(uv));
93 GCObject *o = obj2gco(uv);83 L->openupval = uv->u.open.next; /* remove from `open' list */
94 lua_assert(!isblack(o) && uv->v != &uv->u.value);84 if (uv->refcount == 0) /* no references? */
95 L->openupval = uv->next; /* remove from `open' list */85 luaM_free(L, uv); /* free upvalue */
96 if (isdead(g, o))
97 luaF_freeupval(L, uv); /* free upvalue */
98 else {86 else {
99 unlinkupval(uv); /* remove upvalue from 'uvhead' list */
100 setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */87 setobj(L, &uv->u.value, uv->v); /* move value to upvalue slot */
101 uv->v = &uv->u.value; /* now current value lives here */88 uv->v = &uv->u.value; /* now current value lives here */
102 gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */89 luaC_upvalbarrier(L, uv);
103 g->allgc = o;
104 luaC_checkupvalcolor(g, uv);
105 }90 }
106 }91 }
107}92}
108 93
109 94
110Proto *luaF_newproto (lua_State *L) {95Proto *luaF_newproto (lua_State *L) {
111 Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p;96 Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto))->p;
112 f->k = NULL;97 f->k = NULL;
113 f->sizek = 0;98 f->sizek = 0;
114 f->p = NULL;99 f->p = NULL;
src/lfunc.h+24−3
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lfunc.h,v 2.8 2012/05/08 13:53:33 roberto Exp $2** $Id: lfunc.h,v 2.13 2014/02/18 13:39:37 roberto Exp $
3** Auxiliary functions to manipulate prototypes and closures3** Auxiliary functions to manipulate prototypes and closures
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -18,14 +18,35 @@ · 12 unmodified lines
18 cast(int, sizeof(TValue *)*((n)-1)))18 cast(int, sizeof(TValue *)*((n)-1)))
19 19
20 20
21/* test whether thread is in 'twups' list */
22#define isintwups(L) (L->twups != L)
23
24
25/*
26** Upvalues for Lua closures
27*/
28struct UpVal {
29 TValue *v; /* points to stack or to its own value */
30 lu_mem refcount; /* reference counter */
31 union {
32 struct { /* (when open) */
33 UpVal *next; /* linked list */
34 int touched; /* mark to avoid cycles with dead threads */
35 } open;
36 TValue value; /* the value (when closed) */
37 } u;
38};
39
40#define upisopen(up) ((up)->v != &(up)->u.value)
41
42
21LUAI_FUNC Proto *luaF_newproto (lua_State *L);43LUAI_FUNC Proto *luaF_newproto (lua_State *L);
22LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);44LUAI_FUNC Closure *luaF_newCclosure (lua_State *L, int nelems);
23LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);45LUAI_FUNC Closure *luaF_newLclosure (lua_State *L, int nelems);
24LUAI_FUNC UpVal *luaF_newupval (lua_State *L);46LUAI_FUNC void luaF_initupvals (lua_State *L, LClosure *cl);
25LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);47LUAI_FUNC UpVal *luaF_findupval (lua_State *L, StkId level);
26LUAI_FUNC void luaF_close (lua_State *L, StkId level);48LUAI_FUNC void luaF_close (lua_State *L, StkId level);
27LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);49LUAI_FUNC void luaF_freeproto (lua_State *L, Proto *f);
28LUAI_FUNC void luaF_freeupval (lua_State *L, UpVal *uv);
29LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,50LUAI_FUNC const char *luaF_getlocalname (const Proto *func, int local_number,
30 int pc);51 int pc);
31 52
src/lgc.c+287−336
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lgc.c,v 2.141 2013/04/26 18:26:49 roberto Exp $2** $Id: lgc.c,v 2.179 2014/03/21 13:52:33 roberto Exp $
3** Garbage Collector3** Garbage Collector
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -23,6 +23,11 @@ · 17 unmodified lines
23#include "ltm.h"23#include "ltm.h"
24 24
25 25
26/*
27** internal state for collector while inside the atomic phase. The
28** collector should never be in this state while running regular code.
29*/
30#define GCSinsideatomic (GCSpause + 1)
26 31
27/*32/*
28** cost of sweeping one element (the size of a small object divided33** cost of sweeping one element (the size of a small object divided
@@ -33,8 +38,8 @@ · 4 unmodified lines
33/* maximum number of elements to sweep in each single step */38/* maximum number of elements to sweep in each single step */
34#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))39#define GCSWEEPMAX (cast_int((GCSTEPSIZE / GCSWEEPCOST) / 4))
35 40
36/* maximum number of finalizers to call in each GC step */41/* cost of calling one finalizer */
37#define GCFINALIZENUM 442#define GCFINALIZECOST GCSWEEPCOST
38 43
39 44
40/*45/*
@@ -52,10 +57,10 @@ · 11 unmodified lines
52 57
53 58
54/*59/*
55** 'makewhite' erases all color bits plus the old bit and then60** 'makewhite' erases all color bits then sets only the current white
56** sets only the current white bit61** bit
57*/62*/
58#define maskcolors (~(bit2mask(BLACKBIT, OLDBIT) | WHITEBITS))63#define maskcolors (~(bitmask(BLACKBIT) | WHITEBITS))
59#define makewhite(g,x) \64#define makewhite(g,x) \
60 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))65 (gch(x)->marked = cast_byte((gch(x)->marked & maskcolors) | luaC_white(g)))
61 66
@@ -63,7 +68,7 @@ · 1 unmodified line
63#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)68#define black2gray(x) resetbit(gch(x)->marked, BLACKBIT)
64 69
65 70
66#define isfinalized(x) testbit(gch(x)->marked, FINALIZEDBIT)71#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
67 72
68#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))73#define checkdeadkey(n) lua_assert(!ttisdeadkey(gkey(n)) || ttisnil(gval(n)))
69 74
@@ -75,8 +80,8 @@ · 5 unmodified lines
75#define markvalue(g,o) { checkconsistency(o); \80#define markvalue(g,o) { checkconsistency(o); \
76 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }81 if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); }
77 82
78#define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \83#define markobject(g,t) \
79 reallymarkobject(g, obj2gco(t)); }84 { if ((t) && iswhite(obj2gco(t))) reallymarkobject(g, obj2gco(t)); }
80 85
81static void reallymarkobject (global_State *g, GCObject *o);86static void reallymarkobject (global_State *g, GCObject *o);
82 87
@@ -136,8 +141,8 @@ void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v) { · 53 unmodified lines
136 global_State *g = G(L);141 global_State *g = G(L);
137 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));142 lua_assert(isblack(o) && iswhite(v) && !isdead(g, v) && !isdead(g, o));
138 lua_assert(g->gcstate != GCSpause);143 lua_assert(g->gcstate != GCSpause);
139 lua_assert(gch(o)->tt != LUA_TTABLE);144 lua_assert(gch(o)->tt != LUA_TTABLE); /* tables use a back barrier */
140 if (keepinvariantout(g)) /* must keep invariant? */145 if (keepinvariant(g)) /* must keep invariant? */
141 reallymarkobject(g, v); /* restore invariant */146 reallymarkobject(g, v); /* restore invariant */
142 else { /* sweep phase */147 else { /* sweep phase */
143 lua_assert(issweepphase(g));148 lua_assert(issweepphase(g));
@@ -162,64 +167,41 @@ void luaC_barrierback_ (lua_State *L, GCObject *o) { · 18 unmodified lines
162 167
163 168
164/*169/*
165** barrier for prototypes. When creating first closure (cache is170** barrier for assignments to closed upvalues. Because upvalues are
166** NULL), use a forward barrier; this may be the only closure of the171** shared among closures, it is impossible to know the color of all
167** prototype (if it is a "regular" function, with a single instance)172** closures pointing to it. So, we assume that the object being assigned
168** and the prototype may be big, so it is better to avoid traversing173** must be marked.
169** it again. Otherwise, use a backward barrier, to avoid marking all
170** possible instances.
171*/174*/
172LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c) {175LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv) {
173 global_State *g = G(L);176 global_State *g = G(L);
174 lua_assert(isblack(obj2gco(p)));177 GCObject *o = gcvalue(uv->v);
175 if (p->cache == NULL) { /* first time? */178 lua_assert(!upisopen(uv)); /* ensured by macro luaC_upvalbarrier */
176 luaC_objbarrier(L, p, c);179 if (keepinvariant(g))
177 }180 markobject(g, o);
178 else { /* use a backward barrier */
179 black2gray(obj2gco(p)); /* make prototype gray (again) */
180 p->gclist = g->grayagain;
181 g->grayagain = obj2gco(p);
182 }
183}181}
184 182
185 183
186/*184void luaC_fix (lua_State *L, GCObject *o) {
187** check color (and invariants) for an upvalue that was closed,185 global_State *g = G(L);
188** i.e., moved into the 'allgc' list186 lua_assert(g->allgc == o); /* object must be 1st in 'allgc' list! */
189*/187 white2gray(o); /* they will be gray forever */
190void luaC_checkupvalcolor (global_State *g, UpVal *uv) {188 g->allgc = o->gch.next; /* remove object from 'allgc' list */
191 GCObject *o = obj2gco(uv);189 o->gch.next = g->fixedgc; /* link it to 'fixedgc' list */
192 lua_assert(!isblack(o)); /* open upvalues are never black */190 g->fixedgc = o;
193 if (isgray(o)) {
194 if (keepinvariant(g)) {
195 resetoldbit(o); /* see MOVE OLD rule */
196 gray2black(o); /* it is being visited now */
197 markvalue(g, uv->v);
198 }
199 else {
200 lua_assert(issweepphase(g));
201 makewhite(g, o);
202 }
203 }
204}191}
205 192
206 193
207/*194/*
208** create a new collectable object (with given type and size) and link195** create a new collectable object (with given type and size) and link
209** it to '*list'. 'offset' tells how many bytes to allocate before the196** it to 'allgc' list.
210** object itself (used only by states).
211*/197*/
212GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list,198GCObject *luaC_newobj (lua_State *L, int tt, size_t sz) {
213 int offset) {
214 global_State *g = G(L);199 global_State *g = G(L);
215 char *raw = cast(char *, luaM_newobject(L, novariant(tt), sz));200 GCObject *o = cast(GCObject *, luaM_newobject(L, novariant(tt), sz));
216 GCObject *o = obj2gco(raw + offset);
217 if (list == NULL)
218 list = &g->allgc; /* standard list for collectable objects */
219 gch(o)->marked = luaC_white(g);201 gch(o)->marked = luaC_white(g);
220 gch(o)->tt = tt;202 gch(o)->tt = tt;
221 gch(o)->next = *list;203 gch(o)->next = g->allgc;
222 *list = o;204 g->allgc = o;
223 return o;205 return o;
224}206}
225 207
@@ -241,57 +223,53 @@ GCObject *luaC_newobj (lua_State *L, int tt, size_t sz, GCObject **list, · 15 unmodified lines
241** upvalues are already linked in 'headuv' list.)223** upvalues are already linked in 'headuv' list.)
242*/224*/
243static void reallymarkobject (global_State *g, GCObject *o) {225static void reallymarkobject (global_State *g, GCObject *o) {
244 lu_mem size;226 reentry:
245 white2gray(o);227 white2gray(o);
246 switch (gch(o)->tt) {228 switch (gch(o)->tt) {
247 case LUA_TSHRSTR:229 case LUA_TSHRSTR:
248 case LUA_TLNGSTR: {230 case LUA_TLNGSTR: {
249 size = sizestring(gco2ts(o));231 gray2black(o);
250 break; /* nothing else to mark; make it black */232 g->GCmemtrav += sizestring(gco2ts(o));
251 }
252 case LUA_TUSERDATA: {
253 Table *mt = gco2u(o)->metatable;
254 markobject(g, mt);
255 markobject(g, gco2u(o)->env);
256 size = sizeudata(gco2u(o));
257 break;233 break;
258 }234 }
259 case LUA_TUPVAL: {235 case LUA_TUSERDATA: {
260 UpVal *uv = gco2uv(o);236 TValue uvalue;
261 markvalue(g, uv->v);237 markobject(g, gco2u(o)->metatable); /* mark its metatable */
262 if (uv->v != &uv->u.value) /* open? */238 gray2black(o);
263 return; /* open upvalues remain gray */239 g->GCmemtrav += sizeudata(gco2u(o));
264 size = sizeof(UpVal);240 getuservalue(g->mainthread, rawgco2u(o), &uvalue);
241 if (valiswhite(&uvalue)) { /* markvalue(g, &uvalue); */
242 o = gcvalue(&uvalue);
243 goto reentry;
244 }
265 break;245 break;
266 }246 }
267 case LUA_TLCL: {247 case LUA_TLCL: {
268 gco2lcl(o)->gclist = g->gray;248 gco2lcl(o)->gclist = g->gray;
269 g->gray = o;249 g->gray = o;
270 return;250 break;
271 }251 }
272 case LUA_TCCL: {252 case LUA_TCCL: {
273 gco2ccl(o)->gclist = g->gray;253 gco2ccl(o)->gclist = g->gray;
274 g->gray = o;254 g->gray = o;
275 return;255 break;
276 }256 }
277 case LUA_TTABLE: {257 case LUA_TTABLE: {
278 linktable(gco2t(o), &g->gray);258 linktable(gco2t(o), &g->gray);
279 return;259 break;
280 }260 }
281 case LUA_TTHREAD: {261 case LUA_TTHREAD: {
282 gco2th(o)->gclist = g->gray;262 gco2th(o)->gclist = g->gray;
283 g->gray = o;263 g->gray = o;
284 return;264 break;
285 }265 }
286 case LUA_TPROTO: {266 case LUA_TPROTO: {
287 gco2p(o)->gclist = g->gray;267 gco2p(o)->gclist = g->gray;
288 g->gray = o;268 g->gray = o;
289 return;269 break;
290 }270 }
291 default: lua_assert(0); return;271 default: lua_assert(0); break;
292 }272 }
293 gray2black(o);
294 g->GCmemtrav += size;
295}273}
296 274
297 275
@@ -310,29 +288,41 @@ static void markmt (global_State *g) { · 12 unmodified lines
310*/288*/
311static void markbeingfnz (global_State *g) {289static void markbeingfnz (global_State *g) {
312 GCObject *o;290 GCObject *o;
313 for (o = g->tobefnz; o != NULL; o = gch(o)->next) {291 for (o = g->tobefnz; o != NULL; o = gch(o)->next)
314 makewhite(g, o);292 markobject(g, o);
315 reallymarkobject(g, o);
316 }
317}293}
318 294
319 295
320/*296/*
321** mark all values stored in marked open upvalues. (See comment in297** Mark all values stored in marked open upvalues from non-marked threads.
322** 'lstate.h'.)298** (Values from marked threads were already marked when traversing the
299** thread.) Remove from the list threads that no longer have upvalues and
300** not-marked threads.
323*/301*/
324static void remarkupvals (global_State *g) {302static void remarkupvals (global_State *g) {
325 UpVal *uv;303 lua_State *thread;
326 for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) {304 lua_State **p = &g->twups;
327 if (isgray(obj2gco(uv)))305 while ((thread = *p) != NULL) {
328 markvalue(g, uv->v);306 lua_assert(!isblack(obj2gco(thread))); /* threads are never black */
307 if (isgray(obj2gco(thread)) && thread->openupval != NULL)
308 p = &thread->twups; /* keep marked thread with upvalues in the list */
309 else { /* thread is not marked or without upvalues */
310 UpVal *uv;
311 *p = thread->twups; /* remove thread from the list */
312 thread->twups = thread; /* mark that it is out of list */
313 for (uv = thread->openupval; uv != NULL; uv = uv->u.open.next) {
314 if (uv->u.open.touched) {
315 markvalue(g, uv->v); /* remark upvalue's value */
316 uv->u.open.touched = 0;
317 }
318 }
319 }
329 }320 }
330}321}
331 322
332 323
333/*324/*
334** mark root set and reset all gray lists, to start a new325** mark root set and reset all gray lists, to start a new collection
335** incremental (or full) collection
336*/326*/
337static void restartcollection (global_State *g) {327static void restartcollection (global_State *g) {
338 g->gray = g->grayagain = NULL;328 g->gray = g->grayagain = NULL;
@@ -483,11 +473,24 @@ static lu_mem traverseCclosure (global_State *g, CClosure *cl) { · 144 unmodified lines
483 return sizeCclosure(cl->nupvalues);473 return sizeCclosure(cl->nupvalues);
484}474}
485 475
476/*
477** open upvalues point to values in a thread, so those values should
478** be marked when the thread is traversed except in the atomic phase
479** (because then the value cannot be changed by the thread and the
480** thread may not be traversed again)
481*/
486static lu_mem traverseLclosure (global_State *g, LClosure *cl) {482static lu_mem traverseLclosure (global_State *g, LClosure *cl) {
487 int i;483 int i;
488 markobject(g, cl->p); /* mark its prototype */484 markobject(g, cl->p); /* mark its prototype */
489 for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */485 for (i = 0; i < cl->nupvalues; i++) { /* mark its upvalues */
490 markobject(g, cl->upvals[i]);486 UpVal *uv = cl->upvals[i];
487 if (uv != NULL) {
488 if (upisopen(uv) && g->gcstate != GCSinsideatomic)
489 uv->u.open.touched = 1; /* can be marked in 'remarkupvals' */
490 else
491 markvalue(g, uv->v);
492 }
493 }
491 return sizeLclosure(cl->nupvalues);494 return sizeLclosure(cl->nupvalues);
492}495}
493 496
@@ -497,17 +500,27 @@ static lu_mem traversestack (global_State *g, lua_State *th) { · 3 unmodified lines
497 StkId o = th->stack;500 StkId o = th->stack;
498 if (o == NULL)501 if (o == NULL)
499 return 1; /* stack not completely built yet */502 return 1; /* stack not completely built yet */
503 lua_assert(g->gcstate == GCSinsideatomic ||
504 th->openupval == NULL || isintwups(th));
500 for (; o < th->top; o++) /* mark live elements in the stack */505 for (; o < th->top; o++) /* mark live elements in the stack */
501 markvalue(g, o);506 markvalue(g, o);
502 if (g->gcstate == GCSatomic) { /* final traversal? */507 if (g->gcstate == GCSinsideatomic) { /* final traversal? */
503 StkId lim = th->stack + th->stacksize; /* real end of stack */508 StkId lim = th->stack + th->stacksize; /* real end of stack */
504 for (; o < lim; o++) /* clear not-marked stack slice */509 for (; o < lim; o++) /* clear not-marked stack slice */
505 setnilvalue(o);510 setnilvalue(o);
511 /* 'remarkupvals' may have removed thread from 'twups' list */
512 if (!isintwups(th) && th->openupval != NULL) {
513 th->twups = g->twups; /* link it back to the list */
514 g->twups = th;
515 }
506 }516 }
507 else { /* count call infos to compute size */517 else {
508 CallInfo *ci;518 CallInfo *ci;
509 for (ci = &th->base_ci; ci != th->ci; ci = ci->next)519 for (ci = &th->base_ci; ci != th->ci; ci = ci->next)
510 n++;520 n++; /* count call infos to compute size */
521 /* should not change the stack during an emergency gc cycle */
522 if (g->gckind != KGC_EMERGENCY)
523 luaD_shrinkstack(th);
511 }524 }
512 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +525 return sizeof(lua_State) + sizeof(TValue) * th->stacksize +
513 sizeof(CallInfo) * n;526 sizeof(CallInfo) * n;
@@ -660,23 +673,41 @@ static void clearvalues (global_State *g, GCObject *l, GCObject *f) { · 146 unmodified lines
660}673}
661 674
662 675
676void luaC_upvdeccount (lua_State *L, UpVal *uv) {
677 lua_assert(uv->refcount > 0);
678 uv->refcount--;
679 if (uv->refcount == 0 && !upisopen(uv))
680 luaM_free(L, uv);
681}
682
683
684static void freeLclosure (lua_State *L, LClosure *cl) {
685 int i;
686 for (i = 0; i < cl->nupvalues; i++) {
687 UpVal *uv = cl->upvals[i];
688 if (uv)
689 luaC_upvdeccount(L, uv);
690 }
691 luaM_freemem(L, cl, sizeLclosure(cl->nupvalues));
692}
693
694
663static void freeobj (lua_State *L, GCObject *o) {695static void freeobj (lua_State *L, GCObject *o) {
664 switch (gch(o)->tt) {696 switch (gch(o)->tt) {
665 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;697 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
666 case LUA_TLCL: {698 case LUA_TLCL: {
667 luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues));699 freeLclosure(L, gco2lcl(o));
668 break;700 break;
669 }701 }
670 case LUA_TCCL: {702 case LUA_TCCL: {
671 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));703 luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues));
672 break;704 break;
673 }705 }
674 case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break;
675 case LUA_TTABLE: luaH_free(L, gco2t(o)); break;706 case LUA_TTABLE: luaH_free(L, gco2t(o)); break;
676 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;707 case LUA_TTHREAD: luaE_freethread(L, gco2th(o)); break;
677 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;708 case LUA_TUSERDATA: luaM_freemem(L, o, sizeudata(gco2u(o))); break;
678 case LUA_TSHRSTR:709 case LUA_TSHRSTR:
679 G(L)->strt.nuse--;710 luaS_remove(L, rawgco2ts(o)); /* remove it from hash table */
680 /* go through */711 /* go through */
681 case LUA_TLNGSTR: {712 case LUA_TLNGSTR: {
682 luaM_freemem(L, o, sizestring(gco2ts(o)));713 luaM_freemem(L, o, sizestring(gco2ts(o)));
@@ -691,46 +722,17 @@ static void freeobj (lua_State *L, GCObject *o) { · 8 unmodified lines
691static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);722static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count);
692 723
693 724
694/*
695** sweep the (open) upvalues of a thread and resize its stack and
696** list of call-info structures.
697*/
698static void sweepthread (lua_State *L, lua_State *L1) {
699 if (L1->stack == NULL) return; /* stack not completely built yet */
700 sweepwholelist(L, &L1->openupval); /* sweep open upvalues */
701 luaE_freeCI(L1); /* free extra CallInfo slots */
702 /* should not change the stack during an emergency gc cycle */
703 if (G(L)->gckind != KGC_EMERGENCY)
704 luaD_shrinkstack(L1);
705}
706
707
708/*725/*
709** sweep at most 'count' elements from a list of GCObjects erasing dead726** sweep at most 'count' elements from a list of GCObjects erasing dead
710** objects, where a dead (not alive) object is one marked with the "old"727** objects, where a dead (not alive) object is one marked with the "old"
711** (non current) white and not fixed.728** (non current) white and not fixed; change all non-dead objects back
712** In non-generational mode, change all non-dead objects back to white,729** to white, preparing for next collection cycle.
713** preparing for next collection cycle.
714** In generational mode, keep black objects black, and also mark them as
715** old; stop when hitting an old object, as all objects after that
716** one will be old too.
717** When object is a thread, sweep its list of open upvalues too.730** When object is a thread, sweep its list of open upvalues too.
718*/731*/
719static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {732static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) {
720 global_State *g = G(L);733 global_State *g = G(L);
721 int ow = otherwhite(g);734 int ow = otherwhite(g);
722 int toclear, toset; /* bits to clear and to set in all live objects */735 int white = luaC_white(g); /* current white */
723 int tostop; /* stop sweep when this is true */
724 if (isgenerational(g)) { /* generational mode? */
725 toclear = ~0; /* clear nothing */
726 toset = bitmask(OLDBIT); /* set the old bit of all surviving objects */
727 tostop = bitmask(OLDBIT); /* do not sweep old generation */
728 }
729 else { /* normal mode */
730 toclear = maskcolors; /* clear all color bits + old bit */
731 toset = luaC_white(g); /* make object white */
732 tostop = 0; /* do not stop */
733 }
734 while (*p != NULL && count-- > 0) {736 while (*p != NULL && count-- > 0) {
735 GCObject *curr = *p;737 GCObject *curr = *p;
736 int marked = gch(curr)->marked;738 int marked = gch(curr)->marked;
@@ -738,13 +740,8 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 1 unmodified line
738 *p = gch(curr)->next; /* remove 'curr' from list */740 *p = gch(curr)->next; /* remove 'curr' from list */
739 freeobj(L, curr); /* erase 'curr' */741 freeobj(L, curr); /* erase 'curr' */
740 }742 }
741 else {743 else { /* update marks */
742 if (testbits(marked, tostop))744 gch(curr)->marked = cast_byte((marked & maskcolors) | white);
743 return NULL; /* stop sweeping this list */
744 if (gch(curr)->tt == LUA_TTHREAD)
745 sweepthread(L, gco2th(curr)); /* sweep thread's upvalues */
746 /* update marks */
747 gch(curr)->marked = cast_byte((marked & toclear) | toset);
748 p = &gch(curr)->next; /* go to next element */745 p = &gch(curr)->next; /* go to next element */
749 }746 }
750 }747 }
@@ -756,7 +753,7 @@ static GCObject **sweeplist (lua_State *L, GCObject **p, lu_mem count) { · 5 unmodified lines
756** sweep a list until a live object (or end of list)753** sweep a list until a live object (or end of list)
757*/754*/
758static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {755static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) {
759 GCObject ** old = p;756 GCObject **old = p;
760 int i = 0;757 int i = 0;
761 do {758 do {
762 i++;759 i++;
@@ -775,26 +772,26 @@ static GCObject **sweeptolive (lua_State *L, GCObject **p, int *n) { · 12 unmodified lines
775** =======================================================772** =======================================================
776*/773*/
777 774
778static void checkSizes (lua_State *L) {775/*
779 global_State *g = G(L);776** If possible, free concatenation buffer and shrink string table
780 if (g->gckind != KGC_EMERGENCY) { /* do not change sizes in emergency */777*/
781 int hs = g->strt.size / 2; /* half the size of the string table */778static void checkSizes (lua_State *L, global_State *g) {
782 if (g->strt.nuse < cast(lu_int32, hs)) /* using less than that half? */779 if (g->gckind != KGC_EMERGENCY) {
783 luaS_resize(L, hs); /* halve its size */
784 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */780 luaZ_freebuffer(L, &g->buff); /* free concatenation buffer */
781 if (g->strt.nuse < g->strt.size / 4) /* string table too big? */
782 luaS_resize(L, g->strt.size / 2); /* shrink it a little */
785 }783 }
786}784}
787 785
788 786
789static GCObject *udata2finalize (global_State *g) {787static GCObject *udata2finalize (global_State *g) {
790 GCObject *o = g->tobefnz; /* get first element */788 GCObject *o = g->tobefnz; /* get first element */
791 lua_assert(isfinalized(o));789 lua_assert(tofinalize(o));
792 g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */790 g->tobefnz = gch(o)->next; /* remove it from 'tobefnz' list */
793 gch(o)->next = g->allgc; /* return it to 'allgc' list */791 gch(o)->next = g->allgc; /* return it to 'allgc' list */
794 g->allgc = o;792 g->allgc = o;
795 resetbit(gch(o)->marked, SEPARATED); /* mark that it is not in 'tobefnz' */793 resetbit(gch(o)->marked, FINALIZEDBIT); /* object is "normal" again */
796 lua_assert(!isold(o)); /* see MOVE OLD rule */794 if (issweepphase(g))
797 if (!keepinvariantout(g)) /* not keeping invariant? */
798 makewhite(g, o); /* "sweep" object */795 makewhite(g, o); /* "sweep" object */
799 return o;796 return o;
800}797}
@@ -839,25 +836,39 @@ static void GCTM (lua_State *L, int propagateerrors) { · 38 unmodified lines
839 836
840 837
841/*838/*
842** move all unreachable objects (or 'all' objects) that need839** call all pending finalizers
843** finalization from list 'finobj' to list 'tobefnz' (to be finalized)
844*/840*/
845static void separatetobefnz (lua_State *L, int all) {841static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
846 global_State *g = G(L);842 global_State *g = G(L);
847 GCObject **p = &g->finobj;843 while (g->tobefnz)
844 GCTM(L, propagateerrors);
845}
846
847
848/*
849** find last 'next' field in list 'p' list (to add elements in its end)
850*/
851static GCObject **findlast (GCObject **p) {
852 while (*p != NULL)
853 p = &gch(*p)->next;
854 return p;
855}
856
857
858/*
859** move all unreachable objects (or 'all' objects) that need
860** finalization from list 'p' to list 'tobefnz' (to be finalized)
861*/
862static void separatetobefnz (global_State *g, int all) {
848 GCObject *curr;863 GCObject *curr;
849 GCObject **lastnext = &g->tobefnz;864 GCObject **p = &g->finobj;
850 /* find last 'next' field in 'tobefnz' list (to add elements in its end) */865 GCObject **lastnext = findlast(&g->tobefnz);
851 while (*lastnext != NULL)
852 lastnext = &gch(*lastnext)->next;
853 while ((curr = *p) != NULL) { /* traverse all finalizable objects */866 while ((curr = *p) != NULL) { /* traverse all finalizable objects */
854 lua_assert(!isfinalized(curr));867 lua_assert(tofinalize(curr));
855 lua_assert(testbit(gch(curr)->marked, SEPARATED));
856 if (!(iswhite(curr) || all)) /* not being collected? */868 if (!(iswhite(curr) || all)) /* not being collected? */
857 p = &gch(curr)->next; /* don't bother with it */869 p = &gch(curr)->next; /* don't bother with it */
858 else {870 else {
859 l_setbit(gch(curr)->marked, FINALIZEDBIT); /* won't be finalized again */871 *p = gch(curr)->next; /* remove 'curr' from "fin" list */
860 *p = gch(curr)->next; /* remove 'curr' from 'finobj' list */
861 gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */872 gch(curr)->next = *lastnext; /* link at the end of 'tobefnz' list */
862 *lastnext = curr;873 *lastnext = curr;
863 lastnext = &gch(curr)->next;874 lastnext = &gch(curr)->next;
@@ -872,33 +883,30 @@ static void separatetobefnz (lua_State *L, int all) { · 8 unmodified lines
872*/883*/
873void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {884void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) {
874 global_State *g = G(L);885 global_State *g = G(L);
875 if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */886 if (tofinalize(o) || /* obj. is already marked... */
876 isfinalized(o) || /* ... or is finalized... */887 gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
877 gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */
878 return; /* nothing to be done */888 return; /* nothing to be done */
879 else { /* move 'o' to 'finobj' list */889 else { /* move 'o' to 'finobj' list */
880 GCObject **p;890 GCObject **p;
881 GCheader *ho = gch(o);891 if (g->sweepgc == &o->gch.next) { /* avoid removing current sweep object */
882 if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */
883 lua_assert(issweepphase(g));892 lua_assert(issweepphase(g));
884 g->sweepgc = sweeptolive(L, g->sweepgc, NULL);893 g->sweepgc = sweeptolive(L, g->sweepgc, NULL);
885 }894 }
886 /* search for pointer pointing to 'o' */895 /* search for pointer pointing to 'o' */
887 for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }896 for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ }
888 *p = ho->next; /* remove 'o' from root list */897 *p = o->gch.next; /* remove 'o' from its list */
889 ho->next = g->finobj; /* link it in list 'finobj' */898 o->gch.next = g->finobj; /* link it in "fin" list */
890 g->finobj = o;899 g->finobj = o;
891 l_setbit(ho->marked, SEPARATED); /* mark it as such */900 l_setbit(o->gch.marked, FINALIZEDBIT); /* mark it as such */
892 if (!keepinvariantout(g)) /* not keeping invariant? */901 if (issweepphase(g))
893 makewhite(g, o); /* "sweep" object */902 makewhite(g, o); /* "sweep" object */
894 else
895 resetoldbit(o); /* see MOVE OLD rule */
896 }903 }
897}904}
898 905
899/* }====================================================== */906/* }====================================================== */
900 907
901 908
909
902/*910/*
903** {======================================================911** {======================================================
904** GC control912** GC control
@@ -911,87 +919,45 @@ void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { · 6 unmodified lines
911** cycle will start when memory use hits threshold919** cycle will start when memory use hits threshold
912*/920*/
913static void setpause (global_State *g, l_mem estimate) {921static void setpause (global_State *g, l_mem estimate) {
914 l_mem debt, threshold;922 l_mem threshold, debt;
915 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */923 estimate = estimate / PAUSEADJ; /* adjust 'estimate' */
916 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */924 threshold = (g->gcpause < MAX_LMEM / estimate) /* overflow? */
917 ? estimate * g->gcpause /* no overflow */925 ? estimate * g->gcpause /* no overflow */
918 : MAX_LMEM; /* overflow; truncate to maximum */926 : MAX_LMEM; /* overflow; truncate to maximum */
919 debt = -cast(l_mem, threshold - gettotalbytes(g));927 debt = gettotalbytes(g) - threshold;
920 luaE_setdebt(g, debt);928 luaE_setdebt(g, debt);
921}929}
922 930
923 931
924#define sweepphases \
925 (bitmask(GCSsweepstring) | bitmask(GCSsweepudata) | bitmask(GCSsweep))
926
927
928/*932/*
929** enter first sweep phase (strings) and prepare pointers for other933** Enter first sweep phase.
930** sweep phases. The calls to 'sweeptolive' make pointers point to an934** The call to 'sweeptolive' makes pointer point to an object inside
931** object inside the list (instead of to the header), so that the real935** the list (instead of to the header), so that the real sweep do not
932** sweep do not need to skip objects created between "now" and the start936** need to skip objects created between "now" and the start of the real
933** of the real sweep.937** sweep.
934** Returns how many objects it swept.938** Returns how many objects it swept.
935*/939*/
936static int entersweep (lua_State *L) {940static int entersweep (lua_State *L) {
937 global_State *g = G(L);941 global_State *g = G(L);
938 int n = 0;942 int n = 0;
939 g->gcstate = GCSsweepstring;943 g->gcstate = GCSswpallgc;
940 lua_assert(g->sweepgc == NULL && g->sweepfin == NULL);944 lua_assert(g->sweepgc == NULL);
941 /* prepare to sweep strings, finalizable objects, and regular objects */
942 g->sweepstrgc = 0;
943 g->sweepfin = sweeptolive(L, &g->finobj, &n);
944 g->sweepgc = sweeptolive(L, &g->allgc, &n);945 g->sweepgc = sweeptolive(L, &g->allgc, &n);
945 return n;946 return n;
946}947}
947 948
948 949
949/*
950** change GC mode
951*/
952void luaC_changemode (lua_State *L, int mode) {
953 global_State *g = G(L);
954 if (mode == g->gckind) return; /* nothing to change */
955 if (mode == KGC_GEN) { /* change to generational mode */
956 /* make sure gray lists are consistent */
957 luaC_runtilstate(L, bitmask(GCSpropagate));
958 g->GCestimate = gettotalbytes(g);
959 g->gckind = KGC_GEN;
960 }
961 else { /* change to incremental mode */
962 /* sweep all objects to turn them back to white
963 (as white has not changed, nothing extra will be collected) */
964 g->gckind = KGC_NORMAL;
965 entersweep(L);
966 luaC_runtilstate(L, ~sweepphases);
967 }
968}
969
970
971/*
972** call all pending finalizers
973*/
974static void callallpendingfinalizers (lua_State *L, int propagateerrors) {
975 global_State *g = G(L);
976 while (g->tobefnz) {
977 resetoldbit(g->tobefnz);
978 GCTM(L, propagateerrors);
979 }
980}
981
982
983void luaC_freeallobjects (lua_State *L) {950void luaC_freeallobjects (lua_State *L) {
984 global_State *g = G(L);951 global_State *g = G(L);
985 int i;952 separatetobefnz(g, 1); /* separate all objects with finalizers */
986 separatetobefnz(L, 1); /* separate all objects with finalizers */
987 lua_assert(g->finobj == NULL);953 lua_assert(g->finobj == NULL);
988 callallpendingfinalizers(L, 0);954 callallpendingfinalizers(L, 0);
955 lua_assert(g->tobefnz == NULL);
989 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */956 g->currentwhite = WHITEBITS; /* this "white" makes all objects look dead */
990 g->gckind = KGC_NORMAL;957 g->gckind = KGC_NORMAL;
991 sweepwholelist(L, &g->finobj); /* finalizers can create objs. in 'finobj' */958 sweepwholelist(L, &g->finobj);
992 sweepwholelist(L, &g->allgc);959 sweepwholelist(L, &g->allgc);
993 for (i = 0; i < g->strt.size; i++) /* free all string lists */960 sweepwholelist(L, &g->fixedgc); /* collect fixed objects */
994 sweepwholelist(L, &g->strt.hash[i]);
995 lua_assert(g->strt.nuse == 0);961 lua_assert(g->strt.nuse == 0);
996}962}
997 963
@@ -1001,6 +967,7 @@ static l_mem atomic (lua_State *L) { · 3 unmodified lines
1001 l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */967 l_mem work = -cast(l_mem, g->GCmemtrav); /* start counting work */
1002 GCObject *origweak, *origall;968 GCObject *origweak, *origall;
1003 lua_assert(!iswhite(obj2gco(g->mainthread)));969 lua_assert(!iswhite(obj2gco(g->mainthread)));
970 g->gcstate = GCSinsideatomic;
1004 markobject(g, L); /* mark running thread */971 markobject(g, L); /* mark running thread */
1005 /* registry and global metatables may be changed by API */972 /* registry and global metatables may be changed by API */
1006 markvalue(g, &g->l_registry);973 markvalue(g, &g->l_registry);
@@ -1014,14 +981,15 @@ static l_mem atomic (lua_State *L) { · 7 unmodified lines
1014 work -= g->GCmemtrav; /* restart counting */981 work -= g->GCmemtrav; /* restart counting */
1015 convergeephemerons(g);982 convergeephemerons(g);
1016 /* at this point, all strongly accessible objects are marked. */983 /* at this point, all strongly accessible objects are marked. */
1017 /* clear values from weak tables, before checking finalizers */984 /* Clear values from weak tables, before checking finalizers */
1018 clearvalues(g, g->weak, NULL);985 clearvalues(g, g->weak, NULL);
1019 clearvalues(g, g->allweak, NULL);986 clearvalues(g, g->allweak, NULL);
1020 origweak = g->weak; origall = g->allweak;987 origweak = g->weak; origall = g->allweak;
1021 work += g->GCmemtrav; /* stop counting (objects being finalized) */988 work += g->GCmemtrav; /* stop counting (objects being finalized) */
1022 separatetobefnz(L, 0); /* separate objects to be finalized */989 separatetobefnz(g, 0); /* separate objects to be finalized */
990 g->gcfinnum = 1; /* there may be objects to be finalized */
1023 markbeingfnz(g); /* mark objects that will be finalized */991 markbeingfnz(g); /* mark objects that will be finalized */
1024 propagateall(g); /* remark, to propagate `preserveness' */992 propagateall(g); /* remark, to propagate 'resurrection' */
1025 work -= g->GCmemtrav; /* restart counting */993 work -= g->GCmemtrav; /* restart counting */
1026 convergeephemerons(g);994 convergeephemerons(g);
1027 /* at this point, all resurrected objects are marked. */995 /* at this point, all resurrected objects are marked. */
@@ -1037,66 +1005,67 @@ static l_mem atomic (lua_State *L) { · 9 unmodified lines
1037}1005}
1038 1006
1039 1007
1008static lu_mem sweepstep (lua_State *L, global_State *g,
1009 int nextstate, GCObject **nextlist) {
1010 if (g->sweepgc) {
1011 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);
1012 if (g->sweepgc) /* is there still something to sweep? */
1013 return (GCSWEEPMAX * GCSWEEPCOST);
1014 }
1015 /* else enter next state */
1016 g->gcstate = nextstate;
1017 g->sweepgc = nextlist;
1018 return 0;
1019}
1020
1021
1040static lu_mem singlestep (lua_State *L) {1022static lu_mem singlestep (lua_State *L) {
1041 global_State *g = G(L);1023 global_State *g = G(L);
1042 switch (g->gcstate) {1024 switch (g->gcstate) {
1043 case GCSpause: {1025 case GCSpause: {
1044 /* start to count memory traversed */1026 /* start to count memory traversed */
1045 g->GCmemtrav = g->strt.size * sizeof(GCObject*);1027 g->GCmemtrav = g->strt.size * sizeof(GCObject*);
1046 lua_assert(!isgenerational(g));
1047 restartcollection(g);1028 restartcollection(g);
1048 g->gcstate = GCSpropagate;1029 g->gcstate = GCSpropagate;
1049 return g->GCmemtrav;1030 return g->GCmemtrav;
1050 }1031 }
1051 case GCSpropagate: {1032 case GCSpropagate: {
1052 if (g->gray) {1033 lu_mem oldtrav = g->GCmemtrav;
1053 lu_mem oldtrav = g->GCmemtrav;1034 lua_assert(g->gray);
1054 propagatemark(g);1035 propagatemark(g);
1055 return g->GCmemtrav - oldtrav; /* memory traversed in this step */1036 if (g->gray == NULL) /* no more `gray' objects? */
1056 }1037 g->gcstate = GCSatomic; /* finish propagate phase */
1057 else { /* no more `gray' objects */1038 return g->GCmemtrav - oldtrav; /* memory traversed in this step */
1058 lu_mem work;
1059 int sw;
1060 g->gcstate = GCSatomic; /* finish mark phase */
1061 g->GCestimate = g->GCmemtrav; /* save what was counted */;
1062 work = atomic(L); /* add what was traversed by 'atomic' */
1063 g->GCestimate += work; /* estimate of total memory traversed */
1064 sw = entersweep(L);
1065 return work + sw * GCSWEEPCOST;
1066 }
1067 }1039 }
1068 case GCSsweepstring: {1040 case GCSatomic: {
1069 int i;1041 lu_mem work;
1070 for (i = 0; i < GCSWEEPMAX && g->sweepstrgc + i < g->strt.size; i++)1042 int sw;
1071 sweepwholelist(L, &g->strt.hash[g->sweepstrgc + i]);1043 propagateall(g); /* make sure gray list is empty */
1072 g->sweepstrgc += i;1044 g->GCestimate = g->GCmemtrav; /* save what was counted */;
1073 if (g->sweepstrgc >= g->strt.size) /* no more strings to sweep? */1045 work = atomic(L); /* work is what was traversed by 'atomic' */
1074 g->gcstate = GCSsweepudata;1046 g->GCestimate += work; /* estimate of total memory traversed */
1075 return i * GCSWEEPCOST;1047 sw = entersweep(L);
1048 return work + sw * GCSWEEPCOST;
1076 }1049 }
1077 case GCSsweepudata: {1050 case GCSswpallgc: { /* sweep "regular" objects */
1078 if (g->sweepfin) {1051 return sweepstep(L, g, GCSswpfinobj, &g->finobj);
1079 g->sweepfin = sweeplist(L, g->sweepfin, GCSWEEPMAX);
1080 return GCSWEEPMAX*GCSWEEPCOST;
1081 }
1082 else {
1083 g->gcstate = GCSsweep;
1084 return 0;
1085 }
1086 }1052 }
1087 case GCSsweep: {1053 case GCSswpfinobj: { /* sweep objects with finalizers */
1088 if (g->sweepgc) {1054 return sweepstep(L, g, GCSswptobefnz, &g->tobefnz);
1089 g->sweepgc = sweeplist(L, g->sweepgc, GCSWEEPMAX);1055 }
1090 return GCSWEEPMAX*GCSWEEPCOST;1056 case GCSswptobefnz: { /* sweep objects to be finalized */
1091 }1057 return sweepstep(L, g, GCSswpend, NULL);
1092 else {1058 }
1093 /* sweep main thread */1059 case GCSswpend: { /* finish sweeps */
1094 GCObject *mt = obj2gco(g->mainthread);1060 makewhite(g, obj2gco(g->mainthread)); /* sweep main thread */
1095 sweeplist(L, &mt, 1);1061 checkSizes(L, g);
1096 checkSizes(L);1062 g->gcstate = GCScallfin;
1097 g->gcstate = GCSpause; /* finish collection */1063 return 0;
1098 return GCSWEEPCOST;1064 }
1099 }1065 case GCScallfin: { /* state to finish calling finalizers */
1066 /* do nothing here; should be handled by 'luaC_forcestep' */
1067 g->gcstate = GCSpause; /* finish collection */
1068 return 0;
1100 }1069 }
1101 default: lua_assert(0); return 0;1070 default: lua_assert(0); return 0;
1102 }1071 }
@@ -1114,88 +1083,74 @@ void luaC_runtilstate (lua_State *L, int statesmask) { · 11 unmodified lines
1114}1083}
1115 1084
1116 1085
1117static void generationalcollection (lua_State *L) {1086/*
1087** run a few (up to 'g->gcfinnum') finalizers
1088*/
1089static int runafewfinalizers (lua_State *L) {
1118 global_State *g = G(L);1090 global_State *g = G(L);
1119 lua_assert(g->gcstate == GCSpropagate);1091 unsigned int i;
1120 if (g->GCestimate == 0) { /* signal for another major collection? */1092 lua_assert(!g->tobefnz || g->gcfinnum > 0);
1121 luaC_fullgc(L, 0); /* perform a full regular collection */1093 for (i = 0; g->tobefnz && i < g->gcfinnum; i++)
1122 g->GCestimate = gettotalbytes(g); /* update control */1094 GCTM(L, 1); /* call one finalizer */
1123 }1095 g->gcfinnum = (!g->tobefnz) ? 0 /* nothing more to finalize? */
1124 else {1096 : g->gcfinnum * 2; /* else call a few more next time */
1125 lu_mem estimate = g->GCestimate;1097 return i;
1126 luaC_runtilstate(L, bitmask(GCSpause)); /* run complete (minor) cycle */
1127 g->gcstate = GCSpropagate; /* skip restart */
1128 if (gettotalbytes(g) > (estimate / 100) * g->gcmajorinc)
1129 g->GCestimate = 0; /* signal for a major collection */
1130 else
1131 g->GCestimate = estimate; /* keep estimate from last major coll. */
1132
1133 }
1134 setpause(g, gettotalbytes(g));
1135 lua_assert(g->gcstate == GCSpropagate);
1136}1098}
1137 1099
1138 1100
1139static void incstep (lua_State *L) {1101/*
1140 global_State *g = G(L);1102** get GC debt and convert it from Kb to 'work units' (avoid zero debt
1103** and overflows)
1104*/
1105static l_mem getdebt (global_State *g) {
1141 l_mem debt = g->GCdebt;1106 l_mem debt = g->GCdebt;
1142 int stepmul = g->gcstepmul;1107 int stepmul = g->gcstepmul;
1143 if (stepmul < 40) stepmul = 40; /* avoid ridiculous low values (and 0) */
1144 /* convert debt from Kb to 'work units' (avoid zero debt and overflows) */
1145 debt = (debt / STEPMULADJ) + 1;1108 debt = (debt / STEPMULADJ) + 1;
1146 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;1109 debt = (debt < MAX_LMEM / stepmul) ? debt * stepmul : MAX_LMEM;
1147 do { /* always perform at least one single step */1110 return debt;
1148 lu_mem work = singlestep(L); /* do some work */
1149 debt -= work;
1150 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1151 if (g->gcstate == GCSpause)
1152 setpause(g, g->GCestimate); /* pause until next cycle */
1153 else {
1154 debt = (debt / stepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1155 luaE_setdebt(g, debt);
1156 }
1157}1111}
1158 1112
1159
1160/*1113/*
1161** performs a basic GC step1114** performs a basic GC step when collector is running
1162*/
1163void luaC_forcestep (lua_State *L) {
1164 global_State *g = G(L);
1165 int i;
1166 if (isgenerational(g)) generationalcollection(L);
1167 else incstep(L);
1168 /* run a few finalizers (or all of them at the end of a collect cycle) */
1169 for (i = 0; g->tobefnz && (i < GCFINALIZENUM || g->gcstate == GCSpause); i++)
1170 GCTM(L, 1); /* call one finalizer */
1171}
1172
1173
1174/*
1175** performs a basic GC step only if collector is running
1176*/1115*/
1177void luaC_step (lua_State *L) {1116void luaC_step (lua_State *L) {
1178 global_State *g = G(L);1117 global_State *g = G(L);
1179 if (g->gcrunning) luaC_forcestep(L);1118 l_mem debt = getdebt(g);
1180 else luaE_setdebt(g, -GCSTEPSIZE); /* avoid being called too often */1119 if (!g->gcrunning) { /* not running? */
1120 luaE_setdebt(g, -GCSTEPSIZE * 10); /* avoid being called too often */
1121 return;
1122 }
1123 do {
1124 if (g->gcstate == GCScallfin && g->tobefnz) {
1125 unsigned int n = runafewfinalizers(L);
1126 debt -= (n * GCFINALIZECOST);
1127 }
1128 else { /* perform one single step */
1129 lu_mem work = singlestep(L);
1130 debt -= work;
1131 }
1132 } while (debt > -GCSTEPSIZE && g->gcstate != GCSpause);
1133 if (g->gcstate == GCSpause)
1134 setpause(g, g->GCestimate); /* pause until next cycle */
1135 else {
1136 debt = (debt / g->gcstepmul) * STEPMULADJ; /* convert 'work units' to Kb */
1137 luaE_setdebt(g, debt);
1138 runafewfinalizers(L);
1139 }
1181}1140}
1182 1141
1183 1142
1184
1185/*1143/*
1186** performs a full GC cycle; if "isemergency", does not call1144** performs a full GC cycle; if "isemergency", does not call
1187** finalizers (which could change stack positions)1145** finalizers (which could change stack positions)
1188*/1146*/
1189void luaC_fullgc (lua_State *L, int isemergency) {1147void luaC_fullgc (lua_State *L, int isemergency) {
1190 global_State *g = G(L);1148 global_State *g = G(L);
1191 int origkind = g->gckind;1149 lua_assert(g->gckind == KGC_NORMAL);
1192 lua_assert(origkind != KGC_EMERGENCY);
1193 if (isemergency) /* do not run finalizers during emergency GC */1150 if (isemergency) /* do not run finalizers during emergency GC */
1194 g->gckind = KGC_EMERGENCY;1151 g->gckind = KGC_EMERGENCY;
1195 else {1152 else
1196 g->gckind = KGC_NORMAL;
1197 callallpendingfinalizers(L, 1);1153 callallpendingfinalizers(L, 1);
1198 }
1199 if (keepinvariant(g)) { /* may there be some black objects? */1154 if (keepinvariant(g)) { /* may there be some black objects? */
1200 /* must sweep all objects to turn them back to white1155 /* must sweep all objects to turn them back to white
1201 (as white has not changed, nothing will be collected) */1156 (as white has not changed, nothing will be collected) */
@@ -1205,11 +1160,7 @@ void luaC_fullgc (lua_State *L, int isemergency) { · 3 unmodified lines
1205 luaC_runtilstate(L, bitmask(GCSpause));1160 luaC_runtilstate(L, bitmask(GCSpause));
1206 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */1161 luaC_runtilstate(L, ~bitmask(GCSpause)); /* start new collection */
1207 luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */1162 luaC_runtilstate(L, bitmask(GCSpause)); /* run entire collection */
1208 if (origkind == KGC_GEN) { /* generational mode? */1163 g->gckind = KGC_NORMAL;
1209 /* generational mode must be kept in propagate phase */
1210 luaC_runtilstate(L, bitmask(GCSpropagate));
1211 }
1212 g->gckind = origkind;
1213 setpause(g, gettotalbytes(g));1164 setpause(g, gettotalbytes(g));
1214 if (!isemergency) /* do not run finalizers during emergency GC */1165 if (!isemergency) /* do not run finalizers during emergency GC */
1215 callallpendingfinalizers(L, 1);1166 callallpendingfinalizers(L, 1);
src/lgc.h+30−49
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lgc.h,v 2.58 2012/09/11 12:53:08 roberto Exp $2** $Id: lgc.h,v 2.82 2014/03/19 18:51:16 roberto Exp $
3** Garbage Collector3** Garbage Collector
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -38,36 +38,27 @@ · 32 unmodified lines
38*/38*/
39#define GCSpropagate 039#define GCSpropagate 0
40#define GCSatomic 140#define GCSatomic 1
41#define GCSsweepstring 241#define GCSswpallgc 2
42#define GCSsweepudata 342#define GCSswpfinobj 3
43#define GCSsweep 443#define GCSswptobefnz 4
44#define GCSpause 544#define GCSswpend 5
45#define GCScallfin 6
46#define GCSpause 7
45 47
46 48
47#define issweepphase(g) \49#define issweepphase(g) \
48 (GCSsweepstring <= (g)->gcstate && (g)->gcstate <= GCSsweep)50 (GCSswpallgc <= (g)->gcstate && (g)->gcstate <= GCSswpend)
49 51
50#define isgenerational(g) ((g)->gckind == KGC_GEN)
51 52
52/*53/*
53** macros to tell when main invariant (white objects cannot point to black54** macro to tell when main invariant (white objects cannot point to black
54** ones) must be kept. During a non-generational collection, the sweep55** ones) must be kept. During a collection, the sweep
55** phase may break the invariant, as objects turned white may point to56** phase may break the invariant, as objects turned white may point to
56** still-black objects. The invariant is restored when sweep ends and57** still-black objects. The invariant is restored when sweep ends and
57** all objects are white again. During a generational collection, the58** all objects are white again.
58** invariant must be kept all times.
59*/59*/
60 60
61#define keepinvariant(g) (isgenerational(g) || g->gcstate <= GCSatomic)61#define keepinvariant(g) ((g)->gcstate <= GCSatomic)
62
63
64/*
65** Outside the collector, the state in generational mode is kept in
66** 'propagate', so 'keepinvariant' is always true.
67*/
68#define keepinvariantout(g) \
69 check_exp(g->gcstate == GCSpropagate || !isgenerational(g), \
70 g->gcstate <= GCSatomic)
71 62
72 63
73/*64/*
@@ -87,10 +78,7 @@ · 13 unmodified lines
87#define WHITE0BIT 0 /* object is white (type 0) */78#define WHITE0BIT 0 /* object is white (type 0) */
88#define WHITE1BIT 1 /* object is white (type 1) */79#define WHITE1BIT 1 /* object is white (type 1) */
89#define BLACKBIT 2 /* object is black */80#define BLACKBIT 2 /* object is black */
90#define FINALIZEDBIT 3 /* object has been separated for finalization */81#define FINALIZEDBIT 3 /* object has been marked for finalization */
91#define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */
92#define FIXEDBIT 5 /* object is fixed (should not be collected) */
93#define OLDBIT 6 /* object is old (only in generational mode) */
94/* bit 7 is currently used by tests (luaL_checkmemory) */82/* bit 7 is currently used by tests (luaL_checkmemory) */
95 83
96#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)84#define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT)
@@ -101,21 +89,15 @@ · 4 unmodified lines
101#define isgray(x) /* neither white nor black */ \89#define isgray(x) /* neither white nor black */ \
102 (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))90 (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT)))
103 91
104#define isold(x) testbit((x)->gch.marked, OLDBIT)92#define tofinalize(x) testbit((x)->gch.marked, FINALIZEDBIT)
105 93
106/* MOVE OLD rule: whenever an object is moved to the beginning of94#define otherwhite(g) ((g)->currentwhite ^ WHITEBITS)
107 a GC list, its old bit must be cleared */
108#define resetoldbit(o) resetbit((o)->gch.marked, OLDBIT)
109
110#define otherwhite(g) (g->currentwhite ^ WHITEBITS)
111#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))95#define isdeadm(ow,m) (!(((m) ^ WHITEBITS) & (ow)))
112#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked)96#define isdead(g,v) isdeadm(otherwhite(g), (v)->gch.marked)
113 97
114#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)98#define changewhite(x) ((x)->gch.marked ^= WHITEBITS)
115#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)99#define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT)
116 100
117#define valiswhite(x) (iscollectable(x) && iswhite(gcvalue(x)))
118
119#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)101#define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS)
120 102
121 103
@@ -124,34 +106,33 @@ · 2 unmodified lines
124#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);)106#define luaC_checkGC(L) luaC_condGC(L, luaC_step(L);)
125 107
126 108
127#define luaC_barrier(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \109#define luaC_barrier(L,p,v) { \
110 if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \
128 luaC_barrier_(L,obj2gco(p),gcvalue(v)); }111 luaC_barrier_(L,obj2gco(p),gcvalue(v)); }
129 112
130#define luaC_barrierback(L,p,v) { if (valiswhite(v) && isblack(obj2gco(p))) \113#define luaC_barrierback(L,p,v) { \
131 luaC_barrierback_(L,p); }114 if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \
115 luaC_barrierback_(L,obj2gco(p)); }
132 116
133#define luaC_objbarrier(L,p,o) \117#define luaC_objbarrier(L,p,o) { \
134 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) \118 if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \
135 luaC_barrier_(L,obj2gco(p),obj2gco(o)); }119 luaC_barrier_(L,obj2gco(p),obj2gco(o)); }
136 120
137#define luaC_objbarrierback(L,p,o) \121#define luaC_upvalbarrier(L,uv) \
138 { if (iswhite(obj2gco(o)) && isblack(obj2gco(p))) luaC_barrierback_(L,p); }122 { if (iscollectable((uv)->v) && !upisopen(uv)) \
139 123 luaC_upvalbarrier_(L,uv); }
140#define luaC_barrierproto(L,p,c) \
141 { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); }
142 124
125LUAI_FUNC void luaC_fix (lua_State *L, GCObject *o);
143LUAI_FUNC void luaC_freeallobjects (lua_State *L);126LUAI_FUNC void luaC_freeallobjects (lua_State *L);
144LUAI_FUNC void luaC_step (lua_State *L);127LUAI_FUNC void luaC_step (lua_State *L);
145LUAI_FUNC void luaC_forcestep (lua_State *L);
146LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);128LUAI_FUNC void luaC_runtilstate (lua_State *L, int statesmask);
147LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);129LUAI_FUNC void luaC_fullgc (lua_State *L, int isemergency);
148LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz,130LUAI_FUNC GCObject *luaC_newobj (lua_State *L, int tt, size_t sz);
149 GCObject **list, int offset);
150LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);131LUAI_FUNC void luaC_barrier_ (lua_State *L, GCObject *o, GCObject *v);
151LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);132LUAI_FUNC void luaC_barrierback_ (lua_State *L, GCObject *o);
152LUAI_FUNC void luaC_barrierproto_ (lua_State *L, Proto *p, Closure *c);133LUAI_FUNC void luaC_upvalbarrier_ (lua_State *L, UpVal *uv);
153LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);134LUAI_FUNC void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt);
154LUAI_FUNC void luaC_checkupvalcolor (global_State *g, UpVal *uv);135LUAI_FUNC void luaC_upvdeccount (lua_State *L, UpVal *uv);
155LUAI_FUNC void luaC_changemode (lua_State *L, int mode);136
156 137
157#endif138#endif
src/linit.c+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: linit.c,v 1.32 2011/04/08 19:17:36 roberto Exp $2** $Id: linit.c,v 1.33 2014/02/06 17:32:33 roberto Exp $
3** Initialization of libraries for lua.c and other clients3** Initialization of libraries for lua.c and other clients
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -34,6 +34,7 @@ static const luaL_Reg loadedlibs[] = { · 28 unmodified lines
34 {LUA_IOLIBNAME, luaopen_io},34 {LUA_IOLIBNAME, luaopen_io},
35 {LUA_OSLIBNAME, luaopen_os},35 {LUA_OSLIBNAME, luaopen_os},
36 {LUA_STRLIBNAME, luaopen_string},36 {LUA_STRLIBNAME, luaopen_string},
37 {LUA_UTF8LIBNAME, luaopen_utf8},
37 {LUA_BITLIBNAME, luaopen_bit32},38 {LUA_BITLIBNAME, luaopen_bit32},
38 {LUA_MATHLIBNAME, luaopen_math},39 {LUA_MATHLIBNAME, luaopen_math},
39 {LUA_DBLIBNAME, luaopen_debug},40 {LUA_DBLIBNAME, luaopen_debug},
src/liolib.c+61−58
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: liolib.c,v 2.114 2013/06/07 19:01:35 roberto Exp $2** $Id: liolib.c,v 2.120 2014/03/19 18:57:42 roberto Exp $
3** Standard I/O (and system) library3** Standard I/O (and system) library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -29,14 +29,14 @@ · 23 unmodified lines
29#include "lualib.h"29#include "lualib.h"
30 30
31 31
32#if !defined(lua_checkmode)32#if !defined(l_checkmode)
33 33
34/*34/*
35** Check whether 'mode' matches '[rwa]%+?b?'.35** Check whether 'mode' matches '[rwa]%+?b?'.
36** Change this macro to accept other modes for 'fopen' besides36** Change this macro to accept other modes for 'fopen' besides
37** the standard ones.37** the standard ones.
38*/38*/
39#define lua_checkmode(mode) \39#define l_checkmode(mode) \
40 (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \40 (*mode != '\0' && strchr("rwa", *(mode++)) != NULL && \
41 (*mode != '+' || ++mode) && /* skip if char is '+' */ \41 (*mode != '+' || ++mode) && /* skip if char is '+' */ \
42 (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \42 (*mode != 'b' || ++mode) && /* skip if char is 'b' */ \
@@ -46,45 +46,61 @@ · 3 unmodified lines
46 46
47/*47/*
48** {======================================================48** {======================================================
49** lua_popen spawns a new process connected to the current49** l_popen spawns a new process connected to the current
50** one through the file streams.50** one through the file streams.
51** =======================================================51** =======================================================
52*/52*/
53 53
54#if !defined(lua_popen) /* { */54#if !defined(l_popen) /* { */
55 55
56#if defined(LUA_USE_POPEN) /* { */56#if defined(LUA_USE_POSIX) /* { */
57 57
58#define lua_popen(L,c,m) ((void)L, fflush(NULL), popen(c,m))58#define l_popen(L,c,m) (fflush(NULL), popen(c,m))
59#define lua_pclose(L,file) ((void)L, pclose(file))59#define l_pclose(L,file) (pclose(file))
60 60
61#elif defined(LUA_WIN) /* }{ */61#elif defined(LUA_WIN) /* }{ */
62 62
63#define lua_popen(L,c,m) ((void)L, _popen(c,m))63#define l_popen(L,c,m) (_popen(c,m))
64#define lua_pclose(L,file) ((void)L, _pclose(file))64#define l_pclose(L,file) (_pclose(file))
65
66 65
67#else /* }{ */66#else /* }{ */
68 67
69#define lua_popen(L,c,m) ((void)((void)c, m), \68/* ANSI definitions */
70 luaL_error(L, LUA_QL("popen") " not supported"), (FILE*)0)69#define l_popen(L,c,m) \
71#define lua_pclose(L,file) ((void)((void)L, file), -1)70 ((void)((void)c, m), \
72 71 luaL_error(L, LUA_QL("popen") " not supported"), \
72 (FILE*)0)
73#define l_pclose(L,file) ((void)L, (void)file, -1)
73 74
74#endif /* } */75#endif /* } */
75 76
76#endif /* } */77#endif /* } */
77 78
78/* }====================================================== */79/* }====================================================== */
79 80
80 81
82#if !defined(l_getc) /* { */
83
84#if defined(LUA_USE_POSIX)
85#define l_getc(f) getc_unlocked(f)
86#define l_lockfile(f) flockfile(f)
87#define l_unlockfile(f) funlockfile(f)
88#else
89#define l_getc(f) getc(f)
90#define l_lockfile(f) ((void)0)
91#define l_unlockfile(f) ((void)0)
92#endif
93
94#endif /* } */
95
96
81/*97/*
82** {======================================================98** {======================================================
83** lua_fseek: configuration for longer offsets99** l_fseek: configuration for longer offsets
84** =======================================================100** =======================================================
85*/101*/
86 102
87#if !defined(lua_fseek) && !defined(LUA_ANSI) /* { */103#if !defined(l_fseek) /* { */
88 104
89#if defined(LUA_USE_POSIX) /* { */105#if defined(LUA_USE_POSIX) /* { */
90 106
@@ -94,22 +110,22 @@ · 3 unmodified lines
94 110
95#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \111#elif defined(LUA_WIN) && !defined(_CRTIMP_TYPEINFO) \
96 && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */112 && defined(_MSC_VER) && (_MSC_VER >= 1400) /* }{ */
97/* Windows (but not DDK) and Visual C++ 2005 or higher */
98 113
114/* Windows (but not DDK) and Visual C++ 2005 or higher */
99#define l_fseek(f,o,w) _fseeki64(f,o,w)115#define l_fseek(f,o,w) _fseeki64(f,o,w)
100#define l_ftell(f) _ftelli64(f)116#define l_ftell(f) _ftelli64(f)
101#define l_seeknum __int64117#define l_seeknum __int64
102 118
103#endif /* } */119#else /* }{ */
104
105#endif /* } */
106
107 120
108#if !defined(l_fseek) /* default definitions */121/* ANSI definitions */
109#define l_fseek(f,o,w) fseek(f,o,w)122#define l_fseek(f,o,w) fseek(f,o,w)
110#define l_ftell(f) ftell(f)123#define l_ftell(f) ftell(f)
111#define l_seeknum long124#define l_seeknum long
112#endif125
126#endif /* } */
127
128#endif /* } */
113 129
114/* }====================================================== */130/* }====================================================== */
115 131
@@ -228,7 +244,7 @@ static int io_open (lua_State *L) { · 112 unmodified lines
228 const char *mode = luaL_optstring(L, 2, "r");244 const char *mode = luaL_optstring(L, 2, "r");
229 LStream *p = newfile(L);245 LStream *p = newfile(L);
230 const char *md = mode; /* to traverse/check mode */246 const char *md = mode; /* to traverse/check mode */
231 luaL_argcheck(L, lua_checkmode(md), 2, "invalid mode");247 luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
232 p->f = fopen(filename, mode);248 p->f = fopen(filename, mode);
233 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;249 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
234}250}
@@ -239,7 +255,7 @@ static int io_open (lua_State *L) { · 4 unmodified lines
239*/255*/
240static int io_pclose (lua_State *L) {256static int io_pclose (lua_State *L) {
241 LStream *p = tolstream(L);257 LStream *p = tolstream(L);
242 return luaL_execresult(L, lua_pclose(L, p->f));258 return luaL_execresult(L, l_pclose(L, p->f));
243}259}
244 260
245 261
@@ -247,7 +263,7 @@ static int io_popen (lua_State *L) { · 1 unmodified line
247 const char *filename = luaL_checkstring(L, 1);263 const char *filename = luaL_checkstring(L, 1);
248 const char *mode = luaL_optstring(L, 2, "r");264 const char *mode = luaL_optstring(L, 2, "r");
249 LStream *p = newprefile(L);265 LStream *p = newprefile(L);
250 p->f = lua_popen(L, filename, mode);266 p->f = l_popen(L, filename, mode);
251 p->closef = &io_pclose;267 p->closef = &io_pclose;
252 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;268 return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
253}269}
@@ -375,7 +391,7 @@ static int read_number (lua_State *L, FILE *f) { · 121 unmodified lines
375 391
376static int test_eof (lua_State *L, FILE *f) {392static int test_eof (lua_State *L, FILE *f) {
377 int c = getc(f);393 int c = getc(f);
378 ungetc(c, f);394 ungetc(c, f); /* no-op when c == EOF */
379 lua_pushlstring(L, NULL, 0);395 lua_pushlstring(L, NULL, 0);
380 return (c != EOF);396 return (c != EOF);
381}397}
@@ -383,40 +399,27 @@ static int test_eof (lua_State *L, FILE *f) { · 1 unmodified line
383 399
384static int read_line (lua_State *L, FILE *f, int chop) {400static int read_line (lua_State *L, FILE *f, int chop) {
385 luaL_Buffer b;401 luaL_Buffer b;
402 int c;
386 luaL_buffinit(L, &b);403 luaL_buffinit(L, &b);
387 for (;;) {404 l_lockfile(f);
388 size_t l;405 while ((c = l_getc(f)) != EOF && c != '\n')
389 char *p = luaL_prepbuffer(&b);406 luaL_addchar(&b, c);
390 if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */407 l_unlockfile(f);
391 luaL_pushresult(&b); /* close buffer */408 if (!chop && c == '\n') luaL_addchar(&b, c);
392 return (lua_rawlen(L, -1) > 0); /* check whether read something */409 luaL_pushresult(&b); /* close buffer */
393 }410 return (c == '\n' || lua_rawlen(L, -1) > 0);
394 l = strlen(p);
395 if (l == 0 || p[l-1] != '\n')
396 luaL_addsize(&b, l);
397 else {
398 luaL_addsize(&b, l - chop); /* chop 'eol' if needed */
399 luaL_pushresult(&b); /* close buffer */
400 return 1; /* read at least an `eol' */
401 }
402 }
403}411}
404 412
405 413
406#define MAX_SIZE_T (~(size_t)0)
407
408static void read_all (lua_State *L, FILE *f) {414static void read_all (lua_State *L, FILE *f) {
409 size_t rlen = LUAL_BUFFERSIZE; /* how much to read in each cycle */415 size_t nr;
410 luaL_Buffer b;416 luaL_Buffer b;
411 luaL_buffinit(L, &b);417 luaL_buffinit(L, &b);
412 for (;;) {418 do { /* read file in chunks of LUAL_BUFFERSIZE bytes */
413 char *p = luaL_prepbuffsize(&b, rlen);419 char *p = luaL_prepbuffsize(&b, LUAL_BUFFERSIZE);
414 size_t nr = fread(p, sizeof(char), rlen, f);420 nr = fread(p, sizeof(char), LUAL_BUFFERSIZE, f);
415 luaL_addsize(&b, nr);421 luaL_addsize(&b, nr);
416 if (nr < rlen) break; /* eof? */422 } while (nr == LUAL_BUFFERSIZE);
417 else if (rlen <= (MAX_SIZE_T / 4)) /* avoid buffers too large */
418 rlen *= 2; /* double buffer size at each iteration */
419 }
420 luaL_pushresult(&b); /* close buffer */423 luaL_pushresult(&b); /* close buffer */
421}424}
422 425
@@ -566,15 +569,15 @@ static int f_seek (lua_State *L) { · 143 unmodified lines
566 static const char *const modenames[] = {"set", "cur", "end", NULL};569 static const char *const modenames[] = {"set", "cur", "end", NULL};
567 FILE *f = tofile(L);570 FILE *f = tofile(L);
568 int op = luaL_checkoption(L, 2, "cur", modenames);571 int op = luaL_checkoption(L, 2, "cur", modenames);
569 lua_Number p3 = luaL_optnumber(L, 3, 0);572 lua_Integer p3 = luaL_optinteger(L, 3, 0);
570 l_seeknum offset = (l_seeknum)p3;573 l_seeknum offset = (l_seeknum)p3;
571 luaL_argcheck(L, (lua_Number)offset == p3, 3,574 luaL_argcheck(L, (lua_Integer)offset == p3, 3,
572 "not an integer in proper range");575 "not an integer in proper range");
573 op = l_fseek(f, offset, mode[op]);576 op = l_fseek(f, offset, mode[op]);
574 if (op)577 if (op)
575 return luaL_fileresult(L, 0, NULL); /* error */578 return luaL_fileresult(L, 0, NULL); /* error */
576 else {579 else {
577 lua_pushnumber(L, (lua_Number)l_ftell(f));580 lua_pushinteger(L, (lua_Integer)l_ftell(f));
578 return 1;581 return 1;
579 }582 }
580}583}
src/llex.c+80−42
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: llex.c,v 2.67 2013/06/19 14:27:00 roberto Exp $2** $Id: llex.c,v 2.74 2014/02/14 15:23:51 roberto Exp $
3** Lexical Analyzer3** Lexical Analyzer
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -15,6 +15,7 @@ · 9 unmodified lines
15 15
16#include "lctype.h"16#include "lctype.h"
17#include "ldo.h"17#include "ldo.h"
18#include "lgc.h"
18#include "llex.h"19#include "llex.h"
19#include "lobject.h"20#include "lobject.h"
20#include "lparser.h"21#include "lparser.h"
@@ -38,7 +39,8 @@ static const char *const luaX_tokens [] = { · 17 unmodified lines
38 "end", "false", "for", "function", "goto", "if",39 "end", "false", "for", "function", "goto", "if",
39 "in", "local", "nil", "not", "or", "repeat",40 "in", "local", "nil", "not", "or", "repeat",
40 "return", "then", "true", "until", "while",41 "return", "then", "true", "until", "while",
41 "//", "..", "...", "==", ">=", "<=", "~=", "::", "<eof>",42 "//", "..", "...", "==", ">=", "<=", "~=",
43 "<<", ">>", "::", "<eof>",
42 "<number>", "<number>", "<name>", "<string>"44 "<number>", "<number>", "<name>", "<string>"
43};45};
44 46
@@ -64,9 +66,11 @@ static void save (LexState *ls, int c) { · 19 unmodified lines
64 66
65void luaX_init (lua_State *L) {67void luaX_init (lua_State *L) {
66 int i;68 int i;
69 TString *e = luaS_new(L, LUA_ENV); /* create env name */
70 luaC_fix(L, obj2gco(e)); /* never collect this name */
67 for (i=0; i<NUM_RESERVED; i++) {71 for (i=0; i<NUM_RESERVED; i++) {
68 TString *ts = luaS_new(L, luaX_tokens[i]);72 TString *ts = luaS_new(L, luaX_tokens[i]);
69 luaS_fix(ts); /* reserved words are never collected */73 luaC_fix(L, obj2gco(ts)); /* reserved words are never collected */
70 ts->tsv.extra = cast_byte(i+1); /* reserved word */74 ts->tsv.extra = cast_byte(i+1); /* reserved word */
71 }75 }
72}76}
@@ -116,22 +120,25 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) { · 43 unmodified lines
116 120
117 121
118/*122/*
119** creates a new string and anchors it in function's table so that123** creates a new string and anchors it in scanner's table so that
120** it will not be collected until the end of the function's compilation124** it will not be collected until the end of the compilation
121** (by that time it should be anchored in function's prototype)125** (by that time it should be anchored somewhere)
122*/126*/
123TString *luaX_newstring (LexState *ls, const char *str, size_t l) {127TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
124 lua_State *L = ls->L;128 lua_State *L = ls->L;
125 TValue *o; /* entry for `str' */129 TValue *o; /* entry for `str' */
126 TString *ts = luaS_newlstr(L, str, l); /* create new string */130 TString *ts = luaS_newlstr(L, str, l); /* create new string */
127 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */131 setsvalue2s(L, L->top++, ts); /* temporarily anchor it in stack */
128 o = luaH_set(L, ls->fs->h, L->top - 1);132 o = luaH_set(L, ls->h, L->top - 1);
129 if (ttisnil(o)) { /* not in use yet? (see 'addK') */133 if (ttisnil(o)) { /* not in use yet? */
130 /* boolean value does not need GC barrier;134 /* boolean value does not need GC barrier;
131 table has no metatable, so it does not need to invalidate cache */135 table has no metatable, so it does not need to invalidate cache */
132 setbvalue(o, 1); /* t[string] = true */136 setbvalue(o, 1); /* t[string] = true */
133 luaC_checkGC(L);137 luaC_checkGC(L);
134 }138 }
139 else { /* string already present */
140 ts = rawtsvalue(keyfromval(o)); /* re-use value previously stored */
141 }
135 L->top--; /* remove string from stack */142 L->top--; /* remove string from stack */
136 return ts;143 return ts;
137}144}
@@ -163,8 +170,7 @@ void luaX_setinput (lua_State *L, LexState *ls, ZIO *z, TString *source, · 25 unmodified lines
163 ls->linenumber = 1;170 ls->linenumber = 1;
164 ls->lastline = 1;171 ls->lastline = 1;
165 ls->source = source;172 ls->source = source;
166 ls->envn = luaS_new(L, LUA_ENV); /* create env name */173 ls->envn = luaS_new(L, LUA_ENV); /* get env name */
167 luaS_fix(ls->envn); /* never collect this name */
168 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */174 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
169}175}
170 176
@@ -314,40 +320,65 @@ static void read_long_string (LexState *ls, SemInfo *seminfo, int sep) { · 143 unmodified lines
314}320}
315 321
316 322
317static void escerror (LexState *ls, int *c, int n, const char *msg) {323static void esccheck (LexState *ls, int c, const char *msg) {
318 int i;324 if (!c) {
319 luaZ_resetbuffer(ls->buff); /* prepare error message */325 if (ls->current != EOZ)
320 save(ls, '\\');326 save_and_next(ls); /* add current to buffer for error message */
321 for (i = 0; i < n && c[i] != EOZ; i++)327 lexerror(ls, msg, TK_STRING);
322 save(ls, c[i]);328 }
323 lexerror(ls, msg, TK_STRING);329}
330
331
332static int gethexa (LexState *ls) {
333 save_and_next(ls);
334 esccheck (ls, lisxdigit(ls->current), "hexadecimal digit expected");
335 return luaO_hexavalue(ls->current);
324}336}
325 337
326 338
327static int readhexaesc (LexState *ls) {339static int readhexaesc (LexState *ls) {
328 int c[3], i; /* keep input for error message */340 int r = gethexa(ls);
329 int r = 0; /* result accumulator */341 r = (r << 4) + gethexa(ls);
330 c[0] = 'x'; /* for error message */342 luaZ_buffremove(ls->buff, 2); /* remove saved chars from buffer */
331 for (i = 1; i < 3; i++) { /* read two hexadecimal digits */343 return r;
332 c[i] = next(ls);344}
333 if (!lisxdigit(c[i]))345
334 escerror(ls, c, i + 1, "hexadecimal digit expected");346
335 r = (r << 4) + luaO_hexavalue(c[i]);347static unsigned int readutf8esc (LexState *ls) {
348 unsigned int r;
349 int i = 4; /* chars to be removed: '\', 'u', '{', and first digit */
350 save_and_next(ls); /* skip 'u' */
351 esccheck(ls, ls->current == '{', "missing '{'");
352 r = gethexa(ls); /* must have at least one digit */
353 while ((save_and_next(ls), lisxdigit(ls->current))) {
354 i++;
355 r = (r << 4) + luaO_hexavalue(ls->current);
356 esccheck(ls, r <= 0x10FFFF, "UTF-8 value too large");
336 }357 }
358 esccheck(ls, ls->current == '}', "missing '}'");
359 next(ls); /* skip '}' */
360 luaZ_buffremove(ls->buff, i); /* remove saved chars from buffer */
337 return r;361 return r;
338}362}
339 363
340 364
365static void utf8esc (LexState *ls) {
366 char buff[UTF8BUFFSZ];
367 int n = luaO_utf8esc(buff, readutf8esc(ls));
368 for (; n > 0; n--) /* add 'buff' to string */
369 save(ls, buff[UTF8BUFFSZ - n]);
370}
371
372
341static int readdecesc (LexState *ls) {373static int readdecesc (LexState *ls) {
342 int c[3], i;374 int i;
343 int r = 0; /* result accumulator */375 int r = 0; /* result accumulator */
344 for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */376 for (i = 0; i < 3 && lisdigit(ls->current); i++) { /* read up to 3 digits */
345 c[i] = ls->current;377 r = 10*r + ls->current - '0';
346 r = 10*r + c[i] - '0';378 save_and_next(ls);
347 next(ls);
348 }379 }
349 if (r > UCHAR_MAX)380 esccheck(ls, r <= UCHAR_MAX, "decimal escape too large");
350 escerror(ls, c, i, "decimal escape too large");381 luaZ_buffremove(ls->buff, i); /* remove read digits from buffer */
351 return r;382 return r;
352}383}
353 384
@@ -365,7 +396,7 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 11 unmodified lines
365 break; /* to avoid warnings */396 break; /* to avoid warnings */
366 case '\\': { /* escape sequences */397 case '\\': { /* escape sequences */
367 int c; /* final character to be saved */398 int c; /* final character to be saved */
368 next(ls); /* do not save the `\' */399 save_and_next(ls); /* keep '\\' for error messages */
369 switch (ls->current) {400 switch (ls->current) {
370 case 'a': c = '\a'; goto read_save;401 case 'a': c = '\a'; goto read_save;
371 case 'b': c = '\b'; goto read_save;402 case 'b': c = '\b'; goto read_save;
@@ -375,12 +406,14 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 3 unmodified lines
375 case 't': c = '\t'; goto read_save;406 case 't': c = '\t'; goto read_save;
376 case 'v': c = '\v'; goto read_save;407 case 'v': c = '\v'; goto read_save;
377 case 'x': c = readhexaesc(ls); goto read_save;408 case 'x': c = readhexaesc(ls); goto read_save;
409 case 'u': utf8esc(ls); goto no_save;
378 case '\n': case '\r':410 case '\n': case '\r':
379 inclinenumber(ls); c = '\n'; goto only_save;411 inclinenumber(ls); c = '\n'; goto only_save;
380 case '\\': case '\"': case '\'':412 case '\\': case '\"': case '\'':
381 c = ls->current; goto read_save;413 c = ls->current; goto read_save;
382 case EOZ: goto no_save; /* will raise an error next loop */414 case EOZ: goto no_save; /* will raise an error next loop */
383 case 'z': { /* zap following span of spaces */415 case 'z': { /* zap following span of spaces */
416 luaZ_buffremove(ls->buff, 1); /* remove '\\' */
384 next(ls); /* skip the 'z' */417 next(ls); /* skip the 'z' */
385 while (lisspace(ls->current)) {418 while (lisspace(ls->current)) {
386 if (currIsNewline(ls)) inclinenumber(ls);419 if (currIsNewline(ls)) inclinenumber(ls);
@@ -389,15 +422,18 @@ static void read_string (LexState *ls, int del, SemInfo *seminfo) { · 2 unmodified lines
389 goto no_save;422 goto no_save;
390 }423 }
391 default: {424 default: {
392 if (!lisdigit(ls->current))425 esccheck(ls, lisdigit(ls->current), "invalid escape sequence");
393 escerror(ls, &ls->current, 1, "invalid escape sequence");426 c = readdecesc(ls); /* digital escape \ddd */
394 /* digital escape \ddd */
395 c = readdecesc(ls);
396 goto only_save;427 goto only_save;
397 }428 }
398 }429 }
399 read_save: next(ls); /* read next character */430 read_save:
400 only_save: save(ls, c); /* save 'c' */431 next(ls);
432 /* go through */
433 only_save:
434 luaZ_buffremove(ls->buff, 1); /* remove '\\' */
435 save(ls, c);
436 /* go through */
401 no_save: break;437 no_save: break;
402 }438 }
403 default:439 default:
@@ -457,13 +493,15 @@ static int llex (LexState *ls, SemInfo *seminfo) { · 53 unmodified lines
457 }493 }
458 case '<': {494 case '<': {
459 next(ls);495 next(ls);
460 if (ls->current != '=') return '<';496 if (ls->current == '=') { next(ls); return TK_LE; }
461 else { next(ls); return TK_LE; }497 if (ls->current == '<') { next(ls); return TK_SHL; }
498 return '<';
462 }499 }
463 case '>': {500 case '>': {
464 next(ls);501 next(ls);
465 if (ls->current != '=') return '>';502 if (ls->current == '=') { next(ls); return TK_GE; }
466 else { next(ls); return TK_GE; }503 if (ls->current == '>') { next(ls); return TK_SHR; }
504 return '>';
467 }505 }
468 case '/': {506 case '/': {
469 next(ls);507 next(ls);
src/llex.h+3−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: llex.h,v 1.74 2013/04/26 13:07:53 roberto Exp $2** $Id: llex.h,v 1.76 2013/12/30 20:47:58 roberto Exp $
3** Lexical Analyzer3** Lexical Analyzer
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -27,6 +27,7 @@ enum RESERVED { · 21 unmodified lines
27 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,27 TK_RETURN, TK_THEN, TK_TRUE, TK_UNTIL, TK_WHILE,
28 /* other terminal symbols */28 /* other terminal symbols */
29 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,29 TK_IDIV, TK_CONCAT, TK_DOTS, TK_EQ, TK_GE, TK_LE, TK_NE,
30 TK_SHL, TK_SHR,
30 TK_DBCOLON, TK_EOS,31 TK_DBCOLON, TK_EOS,
31 TK_FLT, TK_INT, TK_NAME, TK_STRING32 TK_FLT, TK_INT, TK_NAME, TK_STRING
32};33};
@@ -60,6 +61,7 @@ typedef struct LexState { · 27 unmodified lines
60 struct lua_State *L;61 struct lua_State *L;
61 ZIO *z; /* input stream */62 ZIO *z; /* input stream */
62 Mbuffer *buff; /* buffer for tokens */63 Mbuffer *buff; /* buffer for tokens */
64 Table *h; /* to avoid collection/reuse strings */
63 struct Dyndata *dyd; /* dynamic structures used by the parser */65 struct Dyndata *dyd; /* dynamic structures used by the parser */
64 TString *source; /* current source name */66 TString *source; /* current source name */
65 TString *envn; /* environment variable name */67 TString *envn; /* environment variable name */
src/llimits.h+7−4
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: llimits.h,v 1.108 2013/06/19 14:27:00 roberto Exp $2** $Id: llimits.h,v 1.111 2014/03/07 16:19:00 roberto Exp $
3** Limits, basic types, and some other `installation-dependent' definitions3** Limits, basic types, and some other `installation-dependent' definitions
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -43,11 +43,13 @@ typedef unsigned char lu_byte; · 37 unmodified lines
43#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */43#define MAX_INT (INT_MAX-2) /* maximum value of an int (-2 for safety) */
44 44
45 45
46/* maximum value for a lua_Unsigned */
47#define MAX_UINTEGER (~(lua_Unsigned)0)
48
46/* minimum and maximum values for lua_Integer */49/* minimum and maximum values for lua_Integer */
47#define MAX_INTEGER ((lua_Integer)(~(lua_Unsigned)0 >> 1))50#define MAX_INTEGER ((lua_Integer)(MAX_UINTEGER >> 1))
48#define MIN_INTEGER (~MAX_INTEGER)51#define MIN_INTEGER (~MAX_INTEGER)
49 52
50
51/*53/*
52** conversion of pointer to integer54** conversion of pointer to integer
53** this is for hashing only; there is no problem if the integer55** this is for hashing only; there is no problem if the integer
@@ -104,6 +106,7 @@ typedef LUAI_UACNUMBER l_uacNumber; · 50 unmodified lines
104 106
105#define cast(t, exp) ((t)(exp))107#define cast(t, exp) ((t)(exp))
106 108
109#define cast_void(i) cast(void, (i))
107#define cast_byte(i) cast(lu_byte, (i))110#define cast_byte(i) cast(lu_byte, (i))
108#define cast_num(i) cast(lua_Number, (i))111#define cast_num(i) cast(lua_Number, (i))
109#define cast_int(i) cast(int, (i))112#define cast_int(i) cast(int, (i))
@@ -155,7 +158,7 @@ typedef lu_int32 Instruction; · 45 unmodified lines
155 158
156/* minimum size for the string table (must be power of 2) */159/* minimum size for the string table (must be power of 2) */
157#if !defined(MINSTRTABSIZE)160#if !defined(MINSTRTABSIZE)
158#define MINSTRTABSIZE 32161#define MINSTRTABSIZE 64 /* minimum size for "predefined" strings */
159#endif162#endif
160 163
161 164
src/lmathlib.c+11−4
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lmathlib.c,v 1.90 2013/07/03 17:23:19 roberto Exp $2** $Id: lmathlib.c,v 1.92 2013/07/22 16:05:53 roberto Exp $
3** Standard mathematical library3** Standard mathematical library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -251,9 +251,16 @@ static int math_randomseed (lua_State *L) { · 245 unmodified lines
251}251}
252 252
253 253
254static int math_isfloat (lua_State *L) {254static int math_type (lua_State *L) {
255 luaL_checkany(L, 1);255 luaL_checkany(L, 1);
256 lua_pushboolean(L, (lua_type(L, 1) == LUA_TNUMBER && !lua_isinteger(L, 1)));256 if (lua_type(L, 1) == LUA_TNUMBER) {
257 if (lua_isinteger(L, 1))
258 lua_pushliteral(L, "integer");
259 else
260 lua_pushliteral(L, "float");
261 }
262 else
263 lua_pushnil(L);
257 return 1;264 return 1;
258}265}
259 266
@@ -273,7 +280,6 @@ static const luaL_Reg mathlib[] = { · 13 unmodified lines
273 {"ifloor", math_ifloor},280 {"ifloor", math_ifloor},
274 {"fmod", math_fmod},281 {"fmod", math_fmod},
275 {"frexp", math_frexp},282 {"frexp", math_frexp},
276 {"isfloat", math_isfloat},
277 {"ldexp", math_ldexp},283 {"ldexp", math_ldexp},
278#if defined(LUA_COMPAT_LOG10)284#if defined(LUA_COMPAT_LOG10)
279 {"log10", math_log10},285 {"log10", math_log10},
@@ -291,6 +297,7 @@ static const luaL_Reg mathlib[] = { · 11 unmodified lines
291 {"sqrt", math_sqrt},297 {"sqrt", math_sqrt},
292 {"tanh", math_tanh},298 {"tanh", math_tanh},
293 {"tan", math_tan},299 {"tan", math_tan},
300 {"type", math_type},
294 {NULL, NULL}301 {NULL, NULL}
295};302};
296 303
src/loadlib.c+15−19
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $2** $Id: loadlib.c,v 1.113 2014/03/12 20:57:40 roberto Exp $
3** Dynamic library loader for Lua3** Dynamic library loader for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5**5**
@@ -31,21 +31,21 @@ · 25 unmodified lines
31 31
32 32
33/*33/*
34** LUA_PATH and LUA_CPATH are the names of the environment34** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
35** variables that Lua check to set its paths.35** variables that Lua check to set its paths.
36*/36*/
37#if !defined(LUA_PATH)37#if !defined(LUA_PATH_VAR)
38#define LUA_PATH "LUA_PATH"38#define LUA_PATH_VAR "LUA_PATH"
39#endif39#endif
40 40
41#if !defined(LUA_CPATH)41#if !defined(LUA_CPATH_VAR)
42#define LUA_CPATH "LUA_CPATH"42#define LUA_CPATH_VAR "LUA_CPATH"
43#endif43#endif
44 44
45#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR45#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
46 46
47#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX47#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
48#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX48#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
49 49
50/*50/*
51** LUA_PATH_SEP is the character that separates templates in a path.51** LUA_PATH_SEP is the character that separates templates in a path.
@@ -468,8 +468,7 @@ static int searcher_Croot (lua_State *L) { · 416 unmodified lines
468static int searcher_preload (lua_State *L) {468static int searcher_preload (lua_State *L) {
469 const char *name = luaL_checkstring(L, 1);469 const char *name = luaL_checkstring(L, 1);
470 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");470 lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
471 lua_getfield(L, -1, name);471 if (lua_getfield(L, -1, name) == LUA_TNIL) /* not found? */
472 if (lua_isnil(L, -1)) /* not found? */
473 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);472 lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
474 return 1;473 return 1;
475}474}
@@ -484,8 +483,7 @@ static void findloader (lua_State *L, const char *name) { · 8 unmodified lines
484 luaL_error(L, LUA_QL("package.searchers") " must be a table");483 luaL_error(L, LUA_QL("package.searchers") " must be a table");
485 /* iterate over available searchers to find a loader */484 /* iterate over available searchers to find a loader */
486 for (i = 1; ; i++) {485 for (i = 1; ; i++) {
487 lua_rawgeti(L, 3, i); /* get a searcher */486 if (lua_rawgeti(L, 3, i) == LUA_TNIL) { /* no more searchers? */
488 if (lua_isnil(L, -1)) { /* no more searchers? */
489 lua_pop(L, 1); /* remove nil */487 lua_pop(L, 1); /* remove nil */
490 luaL_pushresult(&msg); /* create error message */488 luaL_pushresult(&msg); /* create error message */
491 luaL_error(L, "module " LUA_QS " not found:%s",489 luaL_error(L, "module " LUA_QS " not found:%s",
@@ -520,8 +518,7 @@ static int ll_require (lua_State *L) { · 28 unmodified lines
520 lua_call(L, 2, 1); /* run loader to load module */518 lua_call(L, 2, 1); /* run loader to load module */
521 if (!lua_isnil(L, -1)) /* non-nil return? */519 if (!lua_isnil(L, -1)) /* non-nil return? */
522 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */520 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */
523 lua_getfield(L, 2, name);521 if (lua_getfield(L, 2, name) == LUA_TNIL) { /* module set no value? */
524 if (lua_isnil(L, -1)) { /* module did not set a value? */
525 lua_pushboolean(L, 1); /* use true as result */522 lua_pushboolean(L, 1); /* use true as result */
526 lua_pushvalue(L, -1); /* extra copy to be returned */523 lua_pushvalue(L, -1); /* extra copy to be returned */
527 lua_setfield(L, 2, name); /* _LOADED[name] = true */524 lua_setfield(L, 2, name); /* _LOADED[name] = true */
@@ -587,9 +584,8 @@ static int ll_module (lua_State *L) { · 59 unmodified lines
587 int lastarg = lua_gettop(L); /* last parameter */584 int lastarg = lua_gettop(L); /* last parameter */
588 luaL_pushmodule(L, modname, 1); /* get/create module table */585 luaL_pushmodule(L, modname, 1); /* get/create module table */
589 /* check whether table already has a _NAME field */586 /* check whether table already has a _NAME field */
590 lua_getfield(L, -1, "_NAME");587 if (lua_getfield(L, -1, "_NAME") != LUA_TNIL)
591 if (!lua_isnil(L, -1)) /* is table an initialized module? */588 lua_pop(L, 1); /* table is an initialized module */
592 lua_pop(L, 1);
593 else { /* no; initialize it */589 else { /* no; initialize it */
594 lua_pop(L, 1);590 lua_pop(L, 1);
595 modinit(L, modname);591 modinit(L, modname);
@@ -703,9 +699,9 @@ LUAMOD_API int luaopen_package (lua_State *L) { · 107 unmodified lines
703#endif699#endif
704 lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */700 lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
705 /* set field 'path' */701 /* set field 'path' */
706 setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);702 setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
707 /* set field 'cpath' */703 /* set field 'cpath' */
708 setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);704 setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
709 /* store config information */705 /* store config information */
710 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"706 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
711 LUA_EXEC_DIR "\n" LUA_IGMARK "\n");707 LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
src/lobject.c+88−38
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lobject.c,v 2.67 2013/06/25 18:58:32 roberto Exp $2** $Id: lobject.c,v 2.76 2014/03/21 13:52:33 roberto Exp $
3** Some generic functions over Lua objects3** Some generic functions over Lua objects
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -77,22 +77,30 @@ static lua_Integer intarith (lua_State *L, int op, lua_Integer v1, · 71 unmodified lines
77 case LUA_OPSUB:return intop(-, v1, v2);77 case LUA_OPSUB:return intop(-, v1, v2);
78 case LUA_OPMUL:return intop(*, v1, v2);78 case LUA_OPMUL:return intop(*, v1, v2);
79 case LUA_OPMOD: return luaV_mod(L, v1, v2);79 case LUA_OPMOD: return luaV_mod(L, v1, v2);
80 case LUA_OPPOW: return luaV_pow(v1, v2);80 case LUA_OPPOW: return luaV_pow(L, v1, v2);
81 case LUA_OPUNM: return -v1;81 case LUA_OPIDIV: return luaV_div(L, v1, v2);
82 case LUA_OPBAND: return intop(&, v1, v2);
83 case LUA_OPBOR: return intop(|, v1, v2);
84 case LUA_OPBXOR: return intop(^, v1, v2);
85 case LUA_OPSHL: return luaV_shiftl(v1, v2);
86 case LUA_OPSHR: return luaV_shiftl(v1, -v2);
87 case LUA_OPUNM: return intop(-, 0, v1);
88 case LUA_OPBNOT: return intop(^, cast_integer(-1), v1);
82 default: lua_assert(0); return 0;89 default: lua_assert(0); return 0;
83 }90 }
84}91}
85 92
86 93
87static lua_Number numarith (int op, lua_Number v1, lua_Number v2) {94static lua_Number numarith (lua_State *L, int op, lua_Number v1,
95 lua_Number v2) {
88 switch (op) {96 switch (op) {
89 case LUA_OPADD: return luai_numadd(NULL, v1, v2);97 case LUA_OPADD: return luai_numadd(L, v1, v2);
90 case LUA_OPSUB: return luai_numsub(NULL, v1, v2);98 case LUA_OPSUB: return luai_numsub(L, v1, v2);
91 case LUA_OPMUL: return luai_nummul(NULL, v1, v2);99 case LUA_OPMUL: return luai_nummul(L, v1, v2);
92 case LUA_OPDIV: return luai_numdiv(NULL, v1, v2);100 case LUA_OPDIV: return luai_numdiv(L, v1, v2);
93 case LUA_OPMOD: return luai_nummod(NULL, v1, v2);101 case LUA_OPMOD: return luai_nummod(L, v1, v2);
94 case LUA_OPPOW: return luai_numpow(NULL, v1, v2);102 case LUA_OPPOW: return luai_numpow(L, v1, v2);
95 case LUA_OPUNM: return luai_numunm(NULL, v1);103 case LUA_OPUNM: return luai_numunm(L, v1);
96 default: lua_assert(0); return 0;104 default: lua_assert(0); return 0;
97 }105 }
98}106}
@@ -100,29 +108,40 @@ static lua_Number numarith (int op, lua_Number v1, lua_Number v2) { · 1 unmodified line
100 108
101void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,109void luaO_arith (lua_State *L, int op, const TValue *p1, const TValue *p2,
102 TValue *res) {110 TValue *res) {
103 if (op == LUA_OPIDIV) { /* operates only on integers */111 switch (op) {
104 lua_Integer i1; lua_Integer i2;112 case LUA_OPIDIV: case LUA_OPBAND: case LUA_OPBOR:
105 if (tointeger(p1, &i1) && tointeger(p2, &i2)) {113 case LUA_OPBXOR: case LUA_OPSHL: case LUA_OPSHR:
106 setivalue(res, luaV_div(L, i1, i2));114 case LUA_OPBNOT: { /* operates only on integers */
107 return;115 lua_Integer i1; lua_Integer i2;
116 if (tointeger(p1, &i1) && tointeger(p2, &i2)) {
117 setivalue(res, intarith(L, op, i1, i2));
118 return;
119 }
120 else break; /* go to the end */
108 }121 }
109 /* else go to the end */122 case LUA_OPDIV: { /* operates only on floats */
110 }123 lua_Number n1; lua_Number n2;
111 else { /* other operations */124 if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
112 lua_Number n1; lua_Number n2;125 setnvalue(res, numarith(L, op, n1, n2));
113 if (ttisinteger(p1) && ttisinteger(p2) && op != LUA_OPDIV &&126 return;
114 (op != LUA_OPPOW || ivalue(p2) >= 0)) {127 }
115 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));128 else break; /* go to the end */
116 return;
117 }129 }
118 else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {130 default: { /* other operations */
119 setnvalue(res, numarith(op, n1, n2));131 lua_Number n1; lua_Number n2;
120 return;132 if (ttisinteger(p1) && ttisinteger(p2)) {
133 setivalue(res, intarith(L, op, ivalue(p1), ivalue(p2)));
134 return;
135 }
136 else if (tonumber(p1, &n1) && tonumber(p2, &n2)) {
137 setnvalue(res, numarith(L, op, n1, n2));
138 return;
139 }
140 else break; /* go to the end */
121 }141 }
122 /* else go to the end */
123 }142 }
124 /* could not perform raw operation; try metmethod */143 /* could not perform raw operation; try metamethod */
125 lua_assert(L != NULL); /* cannot fail when folding (compile time) */144 lua_assert(L != NULL); /* should not fail when folding (compile time) */
126 luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));145 luaT_trybinTM(L, p1, p2, res, cast(TMS, op - LUA_OPADD + TM_ADD));
127}146}
128 147
@@ -141,22 +160,26 @@ static int isneg (const char **s) { · 12 unmodified lines
141 160
142 161
143/*162/*
163** {======================================================
144** lua_strx2number converts an hexadecimal numeric string to a number.164** lua_strx2number converts an hexadecimal numeric string to a number.
145** In C99, 'strtod' does both conversions. C89, however, has no function165** In C99, 'strtod' does both conversions. C89, however, has no function
146** to convert floating hexadecimal strings to numbers. For these166** to convert floating hexadecimal strings to numbers. For these
147** systems, you can leave 'lua_strx2number' undefined and Lua will167** systems, you can leave 'lua_strx2number' undefined and Lua will
148** provide its own implementation.168** provide its own implementation.
169** =======================================================
149*/170*/
150#if defined(LUA_USE_STRTODHEX)171#if !defined(lua_strx2number) /* { */
172
173#if defined(LUA_USE_C99) /* { */
174
151#define lua_strx2number(s,p) lua_str2number(s,p)175#define lua_strx2number(s,p) lua_str2number(s,p)
152#endif
153 176
177#else /* }{ */
154 178
155#if !defined(lua_strx2number)179/* Lua's implementation for 'lua_strx2number' */
156 180
157#include <math.h>181#include <math.h>
158 182
159
160/* maximum number of significant digits to read (to avoid overflows183/* maximum number of significant digits to read (to avoid overflows
161 even with single floats) */184 even with single floats) */
162#define MAXSIGDIG 30185#define MAXSIGDIG 30
@@ -219,7 +242,11 @@ static lua_Number lua_strx2number (const char *s, char **endptr) { · 56 unmodified lines
219 return l_mathop(ldexp)(r, e);242 return l_mathop(ldexp)(r, e);
220}243}
221 244
222#endif245#endif /* } */
246
247#endif /* } */
248
249/* }====================================================== */
223 250
224 251
225int luaO_str2d (const char *s, size_t len, lua_Number *result) {252int luaO_str2d (const char *s, size_t len, lua_Number *result) {
@@ -260,19 +287,36 @@ int luaO_str2int (const char *s, size_t len, lua_Integer *result) { · 34 unmodified lines
260 while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */287 while (lisspace(cast_uchar(*s))) s++; /* skip trailing spaces */
261 if (empty || s != ends) return 0; /* something wrong in the numeral */288 if (empty || s != ends) return 0; /* something wrong in the numeral */
262 else {289 else {
263 if (neg) *result = -cast(lua_Integer, a);290 *result = cast_integer((neg) ? 0u - a : a);
264 else *result = cast(lua_Integer, a);
265 return 1;291 return 1;
266 }292 }
267}293}
268 294
269 295
296int luaO_utf8esc (char *buff, unsigned int x) {
297 int n = 1; /* number of bytes put in buffer (backwards) */
298 if (x < 0x80) /* ascii? */
299 buff[UTF8BUFFSZ - 1] = x;
300 else { /* need continuation bytes */
301 unsigned int mfb = 0x3f; /* maximum that fits in first byte */
302 do {
303 buff[UTF8BUFFSZ - (n++)] = 0x80 | (x & 0x3f); /* add continuation byte */
304 x >>= 6; /* remove added bits */
305 mfb >>= 1; /* now there is one less bit available in first byte */
306 } while (x > mfb); /* still needs continuation byte? */
307 buff[UTF8BUFFSZ - n] = (~mfb << 1) | x; /* add first byte */
308 }
309 return n;
310}
311
312
270static void pushstr (lua_State *L, const char *str, size_t l) {313static void pushstr (lua_State *L, const char *str, size_t l) {
271 setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));314 setsvalue2s(L, L->top++, luaS_newlstr(L, str, l));
272}315}
273 316
274 317
275/* this function handles only `%d', `%c', %f, %p, and `%s' formats */318/* this function handles only '%d', '%c', '%f', '%p', and '%s'
319 conventional formats, plus Lua-specific '%L' and '%U' */
276const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {320const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
277 int n = 0;321 int n = 0;
278 for (;;) {322 for (;;) {
@@ -311,6 +355,12 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) { · 32 unmodified lines
311 pushstr(L, buff, l);355 pushstr(L, buff, l);
312 break;356 break;
313 }357 }
358 case 'U': {
359 char buff[UTF8BUFFSZ];
360 int l = luaO_utf8esc(buff, va_arg(argp, int));
361 pushstr(L, buff + UTF8BUFFSZ - l, l);
362 break;
363 }
314 case '%': {364 case '%': {
315 pushstr(L, "%", 1);365 pushstr(L, "%", 1);
316 break;366 break;
src/lobject.h+25−20
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lobject.h,v 2.78 2013/05/14 15:59:04 roberto Exp $2** $Id: lobject.h,v 2.86 2014/02/19 13:52:42 roberto Exp $
3** Type definitions for Lua objects3** Type definitions for Lua objects
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -20,13 +20,12 @@ · 14 unmodified lines
20** Extra tags for non-values20** Extra tags for non-values
21*/21*/
22#define LUA_TPROTO LUA_NUMTAGS22#define LUA_TPROTO LUA_NUMTAGS
23#define LUA_TUPVAL (LUA_NUMTAGS+1)23#define LUA_TDEADKEY (LUA_NUMTAGS+1)
24#define LUA_TDEADKEY (LUA_NUMTAGS+2)
25 24
26/*25/*
27** number of all possible tags (including LUA_TNONE but excluding DEADKEY)26** number of all possible tags (including LUA_TNONE but excluding DEADKEY)
28*/27*/
29#define LUA_TOTALTAGS (LUA_TUPVAL+2)28#define LUA_TOTALTAGS (LUA_TPROTO + 2)
30 29
31 30
32/*31/*
@@ -147,7 +146,7 @@ typedef struct lua_TValue TValue; · 114 unmodified lines
147#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))146#define ttisCclosure(o) checktag((o), ctb(LUA_TCCL))
148#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))147#define ttisLclosure(o) checktag((o), ctb(LUA_TLCL))
149#define ttislcf(o) checktag((o), LUA_TLCF)148#define ttislcf(o) checktag((o), LUA_TLCF)
150#define ttisuserdata(o) checktag((o), ctb(LUA_TUSERDATA))149#define ttisfulluserdata(o) checktag((o), ctb(LUA_TUSERDATA))
151#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))150#define ttisthread(o) checktag((o), ctb(LUA_TTHREAD))
152#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)151#define ttisdeadkey(o) checktag((o), LUA_TDEADKEY)
153 152
@@ -159,7 +158,7 @@ typedef struct lua_TValue TValue; · 5 unmodified lines
159#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)158#define pvalue(o) check_exp(ttislightuserdata(o), val_(o).p)
160#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts)159#define rawtsvalue(o) check_exp(ttisstring(o), &val_(o).gc->ts)
161#define tsvalue(o) (&rawtsvalue(o)->tsv)160#define tsvalue(o) (&rawtsvalue(o)->tsv)
162#define rawuvalue(o) check_exp(ttisuserdata(o), &val_(o).gc->u)161#define rawuvalue(o) check_exp(ttisfulluserdata(o), &val_(o).gc->u)
163#define uvalue(o) (&rawuvalue(o)->uv)162#define uvalue(o) (&rawuvalue(o)->uv)
164#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)163#define clvalue(o) check_exp(ttisclosure(o), &val_(o).gc->cl)
165#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)164#define clLvalue(o) check_exp(ttisLclosure(o), &val_(o).gc->cl.l)
@@ -311,8 +310,9 @@ typedef union TString { · 145 unmodified lines
311 struct {310 struct {
312 CommonHeader;311 CommonHeader;
313 lu_byte extra; /* reserved words for short strings; "has hash" for longs */312 lu_byte extra; /* reserved words for short strings; "has hash" for longs */
314 unsigned int hash;
315 size_t len; /* number of characters in string */313 size_t len; /* number of characters in string */
314 union TString *hnext; /* linked list for hash table */
315 unsigned int hash;
316 } tsv;316 } tsv;
317} TString;317} TString;
318 318
@@ -331,13 +331,25 @@ typedef union Udata { · 12 unmodified lines
331 L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */331 L_Umaxalign dummy; /* ensures maximum alignment for `local' udata */
332 struct {332 struct {
333 CommonHeader;333 CommonHeader;
334 lu_byte ttuv_; /* user value's tag */
334 struct Table *metatable;335 struct Table *metatable;
335 struct Table *env;
336 size_t len; /* number of bytes */336 size_t len; /* number of bytes */
337 union Value user_; /* user value */
337 } uv;338 } uv;
338} Udata;339} Udata;
339 340
340 341
342#define setuservalue(L,u,o) \
343 { const TValue *io=(o); Udata *iu = (u); \
344 iu->uv.user_ = io->value_; iu->uv.ttuv_ = io->tt_; \
345 checkliveness(G(L),io); }
346
347
348#define getuservalue(L,u,o) \
349 { TValue *io=(o); const Udata *iu = (u); \
350 io->value_ = iu->uv.user_; io->tt_ = iu->uv.ttuv_; \
351 checkliveness(G(L),io); }
352
341 353
342/*354/*
343** Description of an upvalue for function prototypes355** Description of an upvalue for function prototypes
@@ -392,17 +404,7 @@ typedef struct Proto { · 48 unmodified lines
392/*404/*
393** Lua Upvalues405** Lua Upvalues
394*/406*/
395typedef struct UpVal {407typedef struct UpVal UpVal;
396 CommonHeader;
397 TValue *v; /* points to stack or to its own value */
398 union {
399 TValue value; /* the value (when closed) */
400 struct { /* double linked list (when open) */
401 struct UpVal *prev;
402 struct UpVal *next;
403 } l;
404 } u;
405} UpVal;
406 408
407 409
408/*410/*
@@ -444,7 +446,7 @@ typedef union Closure { · 35 unmodified lines
444typedef union TKey {446typedef union TKey {
445 struct {447 struct {
446 TValuefields;448 TValuefields;
447 struct Node *next; /* for chaining */449 int next; /* for chaining (offset for next node) */
448 } nk;450 } nk;
449 TValue tvk;451 TValue tvk;
450} TKey;452} TKey;
@@ -489,9 +491,12 @@ typedef struct Table { · 38 unmodified lines
489 491
490LUAI_DDEC const TValue luaO_nilobject_;492LUAI_DDEC const TValue luaO_nilobject_;
491 493
494/* size of buffer for 'luaO_utf8esc' function */
495#define UTF8BUFFSZ 8
492 496
493LUAI_FUNC int luaO_int2fb (unsigned int x);497LUAI_FUNC int luaO_int2fb (unsigned int x);
494LUAI_FUNC int luaO_fb2int (int x);498LUAI_FUNC int luaO_fb2int (int x);
499LUAI_FUNC int luaO_utf8esc (char *buff, unsigned int x);
495LUAI_FUNC int luaO_ceillog2 (unsigned int x);500LUAI_FUNC int luaO_ceillog2 (unsigned int x);
496LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,501LUAI_FUNC void luaO_arith (lua_State *L, int op, const TValue *p1,
497 const TValue *p2, TValue *res);502 const TValue *p2, TValue *res);
src/lopcodes.c+17−5
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lopcodes.c,v 1.50 2013/04/26 13:07:53 roberto Exp $2** $Id: lopcodes.c,v 1.53 2013/12/30 20:47:58 roberto Exp $
3** Opcodes for Lua virtual machine3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -31,11 +31,17 @@ LUAI_DDEF const char *const luaP_opnames[NUM_OPCODES+1] = { · 25 unmodified lines
31 "ADD",31 "ADD",
32 "SUB",32 "SUB",
33 "MUL",33 "MUL",
34 "DIV",
35 "IDIV",
36 "MOD",34 "MOD",
37 "POW",35 "POW",
36 "DIV",
37 "IDIV",
38 "BAND",
39 "BOR",
40 "BXOR",
41 "SHL",
42 "SHR",
38 "UNM",43 "UNM",
44 "BNOT",
39 "NOT",45 "NOT",
40 "LEN",46 "LEN",
41 "CONCAT",47 "CONCAT",
@@ -80,11 +86,17 @@ LUAI_DDEF const lu_byte luaP_opmodes[NUM_OPCODES] = { · 38 unmodified lines
80 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */86 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_ADD */
81 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */87 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SUB */
82 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */88 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MUL */
83 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
84 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */
85 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */89 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_MOD */
86 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */90 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_POW */
91 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_DIV */
92 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_IDIV */
93 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BAND */
94 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BOR */
95 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_BXOR */
96 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHL */
97 ,opmode(0, 1, OpArgK, OpArgK, iABC) /* OP_SHR */
87 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */98 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_UNM */
99 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_BNOT */
88 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */100 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_NOT */
89 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */101 ,opmode(0, 1, OpArgR, OpArgN, iABC) /* OP_LEN */
90 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */102 ,opmode(0, 1, OpArgR, OpArgR, iABC) /* OP_CONCAT */
src/lopcodes.h+9−3
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lopcodes.h,v 1.143 2013/04/26 13:07:53 roberto Exp $2** $Id: lopcodes.h,v 1.146 2013/12/30 20:47:58 roberto Exp $
3** Opcodes for Lua virtual machine3** Opcodes for Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -187,11 +187,17 @@ OP_SELF,/* A B C R(A+1) := R(B); R(A) := R(B)[RK(C)] */ · 181 unmodified lines
187OP_ADD,/* A B C R(A) := RK(B) + RK(C) */187OP_ADD,/* A B C R(A) := RK(B) + RK(C) */
188OP_SUB,/* A B C R(A) := RK(B) - RK(C) */188OP_SUB,/* A B C R(A) := RK(B) - RK(C) */
189OP_MUL,/* A B C R(A) := RK(B) * RK(C) */189OP_MUL,/* A B C R(A) := RK(B) * RK(C) */
190OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
191OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
192OP_MOD,/* A B C R(A) := RK(B) % RK(C) */190OP_MOD,/* A B C R(A) := RK(B) % RK(C) */
193OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */191OP_POW,/* A B C R(A) := RK(B) ^ RK(C) */
192OP_DIV,/* A B C R(A) := RK(B) / RK(C) */
193OP_IDIV,/* A B C R(A) := RK(B) // RK(C) */
194OP_BAND,/* A B C R(A) := RK(B) & RK(C) */
195OP_BOR,/* A B C R(A) := RK(B) | RK(C) */
196OP_BXOR,/* A B C R(A) := RK(B) ~ RK(C) */
197OP_SHL,/* A B C R(A) := RK(B) << RK(C) */
198OP_SHR,/* A B C R(A) := RK(B) >> RK(C) */
194OP_UNM,/* A B R(A) := -R(B) */199OP_UNM,/* A B R(A) := -R(B) */
200OP_BNOT,/* A B R(A) := ~R(B) */
195OP_NOT,/* A B R(A) := not R(B) */201OP_NOT,/* A B R(A) := not R(B) */
196OP_LEN,/* A B R(A) := length of R(B) */202OP_LEN,/* A B R(A) := length of R(B) */
197 203
src/loslib.c+42−18
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: loslib.c,v 1.41 2013/05/14 15:57:11 roberto Exp $2** $Id: loslib.c,v 1.45 2014/03/20 19:18:54 roberto Exp $
3** Standard Operating System library3** Standard Operating System library
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -20,29 +20,44 @@ · 14 unmodified lines
20#include "lualib.h"20#include "lualib.h"
21 21
22 22
23#if !defined(LUA_STRFTIMEOPTIONS) /* { */
23/*24/*
24** list of valid conversion specifiers for the 'strftime' function25** list of valid conversion specifiers for the 'strftime' function
25*/26*/
26#if !defined(LUA_STRFTIMEOPTIONS)
27 27
28#if !defined(LUA_USE_POSIX)28#if !defined(LUA_USE_POSIX)
29#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }29#define LUA_STRFTIMEOPTIONS { "aAbBcdHIjmMpSUwWxXyYz%", "" }
30#else30#else
31#define LUA_STRFTIMEOPTIONS \31#define LUA_STRFTIMEOPTIONS \
32 { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "" \32 { "aAbBcCdDeFgGhHIjmMnprRStTuUVwWxXyYzZ%", "", \
33 "", "E", "cCxXyY", \33 "E", "cCxXyY", \
34 "O", "deHImMSuUVwWy" }34 "O", "deHImMSuUVwWy" }
35#endif35#endif
36 36
37#endif37#endif /* } */
38
39
40
41#if !defined(l_time_t) /* { */
42/*
43** type to represent time_t in Lua
44*/
45#define l_timet lua_Integer
46#define l_pushtime(L,t) lua_pushinteger(L,(lua_Integer)(t))
47#define l_checktime(L,a) ((time_t)luaL_checkinteger(L,a))
38 48
49#endif /* } */
39 50
40 51
52
53#if !defined(lua_tmpnam) /* { */
41/*54/*
42** By default, Lua uses tmpnam except when POSIX is available, where it55** By default, Lua uses tmpnam except when POSIX is available, where it
43** uses mkstemp.56** uses mkstemp.
44*/57*/
45#if defined(LUA_USE_MKSTEMP)58
59#if defined(LUA_USE_POSIX) /* { */
60
46#include <unistd.h>61#include <unistd.h>
47#define LUA_TMPNAMBUFSIZE 3262#define LUA_TMPNAMBUFSIZE 32
48#define lua_tmpnam(b,e) { \63#define lua_tmpnam(b,e) { \
@@ -51,29 +66,38 @@ · 2 unmodified lines
51 if (e != -1) close(e); \66 if (e != -1) close(e); \
52 e = (e == -1); }67 e = (e == -1); }
53 68
54#elif !defined(lua_tmpnam)69#else /* }{ */
55 70
71/* ANSI definitions */
56#define LUA_TMPNAMBUFSIZE L_tmpnam72#define LUA_TMPNAMBUFSIZE L_tmpnam
57#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }73#define lua_tmpnam(b,e) { e = (tmpnam(b) == NULL); }
58 74
59#endif75#endif /* } */
76
77#endif /* } */
78
60 79
61 80
81#if !defined(l_gmtime) /* { */
62/*82/*
63** By default, Lua uses gmtime/localtime, except when POSIX is available,83** By default, Lua uses gmtime/localtime, except when POSIX is available,
64** where it uses gmtime_r/localtime_r84** where it uses gmtime_r/localtime_r
65*/85*/
66#if defined(LUA_USE_GMTIME_R)86
87#if defined(LUA_USE_POSIX) /* { */
67 88
68#define l_gmtime(t,r) gmtime_r(t,r)89#define l_gmtime(t,r) gmtime_r(t,r)
69#define l_localtime(t,r) localtime_r(t,r)90#define l_localtime(t,r) localtime_r(t,r)
70 91
71#elif !defined(l_gmtime)92#else /* }{ */
72 93
94/* ANSI definitions */
73#define l_gmtime(t,r) ((void)r, gmtime(t))95#define l_gmtime(t,r) ((void)r, gmtime(t))
74#define l_localtime(t,r) ((void)r, localtime(t))96#define l_localtime(t,r) ((void)r, localtime(t))
75 97
76#endif98#endif /* } */
99
100#endif /* } */
77 101
78 102
79 103
@@ -147,8 +171,7 @@ static void setboolfield (lua_State *L, const char *key, int value) { · 67 unmodified lines
147 171
148static int getboolfield (lua_State *L, const char *key) {172static int getboolfield (lua_State *L, const char *key) {
149 int res;173 int res;
150 lua_getfield(L, -1, key);174 res = (lua_getfield(L, -1, key) == LUA_TNIL) ? -1 : lua_toboolean(L, -1);
151 res = lua_isnil(L, -1) ? -1 : lua_toboolean(L, -1);
152 lua_pop(L, 1);175 lua_pop(L, 1);
153 return res;176 return res;
154}177}
@@ -194,7 +217,7 @@ static const char *checkoption (lua_State *L, const char *conv, char *buff) { · 39 unmodified lines
194 217
195static int os_date (lua_State *L) {218static int os_date (lua_State *L) {
196 const char *s = luaL_optstring(L, 1, "%c");219 const char *s = luaL_optstring(L, 1, "%c");
197 time_t t = luaL_opt(L, (time_t)luaL_checkinteger, 2, time(NULL));220 time_t t = luaL_opt(L, l_checktime, 2, time(NULL));
198 struct tm tmr, *stm;221 struct tm tmr, *stm;
199 if (*s == '!') { /* UTC? */222 if (*s == '!') { /* UTC? */
200 stm = l_gmtime(&t, &tmr);223 stm = l_gmtime(&t, &tmr);
@@ -255,17 +278,18 @@ static int os_time (lua_State *L) { · 54 unmodified lines
255 ts.tm_isdst = getboolfield(L, "isdst");278 ts.tm_isdst = getboolfield(L, "isdst");
256 t = mktime(&ts);279 t = mktime(&ts);
257 }280 }
258 if (t == (time_t)(-1))281 if (t != (time_t)(l_timet)t)
282 luaL_error(L, "time result cannot be represented in this Lua instalation");
283 else if (t == (time_t)(-1))
259 lua_pushnil(L);284 lua_pushnil(L);
260 else285 else
261 lua_pushinteger(L, t);286 l_pushtime(L, t);
262 return 1;287 return 1;
263}288}
264 289
265 290
266static int os_difftime (lua_State *L) {291static int os_difftime (lua_State *L) {
267 lua_pushnumber(L, difftime((time_t)(luaL_checkinteger(L, 1)),292 lua_pushnumber(L, difftime((l_checktime(L, 1)), (l_checktime(L, 2))));
268 (time_t)(luaL_optinteger(L, 2, 0))));
269 return 1;293 return 1;
270}294}
271 295
src/lparser.c+37−37
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp $2** $Id: lparser.c,v 2.138 2013/12/30 20:47:58 roberto Exp $
3** Lua Parser3** Lua Parser
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -35,6 +35,10 @@ · 29 unmodified lines
35#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)35#define hasmultret(k) ((k) == VCALL || (k) == VVARARG)
36 36
37 37
38/* because all strings are unified by the scanner, the parser
39 can use pointer equality for string equality */
40#define eqstr(a,b) ((a) == (b))
41
38 42
39/*43/*
40** nodes for block list (list of active blocks)44** nodes for block list (list of active blocks)
@@ -57,16 +61,6 @@ static void statement (LexState *ls); · 16 unmodified lines
57static void expr (LexState *ls, expdesc *v);61static void expr (LexState *ls, expdesc *v);
58 62
59 63
60static void anchor_token (LexState *ls) {
61 /* last token from outer function must be EOS */
62 lua_assert(ls->fs != NULL || ls->t.token == TK_EOS);
63 if (ls->t.token == TK_NAME || ls->t.token == TK_STRING) {
64 TString *ts = ls->t.seminfo.ts;
65 luaX_newstring(ls, getstr(ts), ts->tsv.len);
66 }
67}
68
69
70/* semantic error */64/* semantic error */
71static l_noret semerror (LexState *ls, const char *msg) {65static l_noret semerror (LexState *ls, const char *msg) {
72 ls->t.token = 0; /* remove 'near to' from final message */66 ls->t.token = 0; /* remove 'near to' from final message */
@@ -222,7 +216,7 @@ static int searchupvalue (FuncState *fs, TString *name) { · 149 unmodified lines
222 int i;216 int i;
223 Upvaldesc *up = fs->f->upvalues;217 Upvaldesc *up = fs->f->upvalues;
224 for (i = 0; i < fs->nups; i++) {218 for (i = 0; i < fs->nups; i++) {
225 if (luaS_eqstr(up[i].name, name)) return i;219 if (eqstr(up[i].name, name)) return i;
226 }220 }
227 return -1; /* not found */221 return -1; /* not found */
228}222}
@@ -246,7 +240,7 @@ static int newupvalue (FuncState *fs, TString *name, expdesc *v) { · 17 unmodified lines
246static int searchvar (FuncState *fs, TString *n) {240static int searchvar (FuncState *fs, TString *n) {
247 int i;241 int i;
248 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {242 for (i = cast_int(fs->nactvar) - 1; i >= 0; i--) {
249 if (luaS_eqstr(n, getlocvar(fs, i)->varname))243 if (eqstr(n, getlocvar(fs, i)->varname))
250 return i;244 return i;
251 }245 }
252 return -1; /* not found */246 return -1; /* not found */
@@ -342,7 +336,7 @@ static void closegoto (LexState *ls, int g, Labeldesc *label) { · 89 unmodified lines
342 FuncState *fs = ls->fs;336 FuncState *fs = ls->fs;
343 Labellist *gl = &ls->dyd->gt;337 Labellist *gl = &ls->dyd->gt;
344 Labeldesc *gt = &gl->arr[g];338 Labeldesc *gt = &gl->arr[g];
345 lua_assert(luaS_eqstr(gt->name, label->name));339 lua_assert(eqstr(gt->name, label->name));
346 if (gt->nactvar < label->nactvar) {340 if (gt->nactvar < label->nactvar) {
347 TString *vname = getlocvar(fs, gt->nactvar)->varname;341 TString *vname = getlocvar(fs, gt->nactvar)->varname;
348 const char *msg = luaO_pushfstring(ls->L,342 const char *msg = luaO_pushfstring(ls->L,
@@ -369,7 +363,7 @@ static int findlabel (LexState *ls, int g) { · 20 unmodified lines
369 /* check labels in current block for a match */363 /* check labels in current block for a match */
370 for (i = bl->firstlabel; i < dyd->label.n; i++) {364 for (i = bl->firstlabel; i < dyd->label.n; i++) {
371 Labeldesc *lb = &dyd->label.arr[i];365 Labeldesc *lb = &dyd->label.arr[i];
372 if (luaS_eqstr(lb->name, gt->name)) { /* correct label? */366 if (eqstr(lb->name, gt->name)) { /* correct label? */
373 if (gt->nactvar > lb->nactvar &&367 if (gt->nactvar > lb->nactvar &&
374 (bl->upval || dyd->label.n > bl->firstlabel))368 (bl->upval || dyd->label.n > bl->firstlabel))
375 luaK_patchclose(ls->fs, gt->pc, lb->nactvar);369 luaK_patchclose(ls->fs, gt->pc, lb->nactvar);
@@ -403,7 +397,7 @@ static void findgotos (LexState *ls, Labeldesc *lb) { · 27 unmodified lines
403 Labellist *gl = &ls->dyd->gt;397 Labellist *gl = &ls->dyd->gt;
404 int i = ls->fs->bl->firstgoto;398 int i = ls->fs->bl->firstgoto;
405 while (i < gl->n) {399 while (i < gl->n) {
406 if (luaS_eqstr(gl->arr[i].name, lb->name))400 if (eqstr(gl->arr[i].name, lb->name))
407 closegoto(ls, i, lb);401 closegoto(ls, i, lb);
408 else402 else
409 i++;403 i++;
@@ -525,7 +519,6 @@ static void codeclosure (LexState *ls, expdesc *v) { · 115 unmodified lines
525 519
526 520
527static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {521static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) {
528 lua_State *L = ls->L;
529 Proto *f;522 Proto *f;
530 fs->prev = ls->fs; /* linked list of funcstates */523 fs->prev = ls->fs; /* linked list of funcstates */
531 fs->ls = ls;524 fs->ls = ls;
@@ -544,10 +537,6 @@ static void open_func (LexState *ls, FuncState *fs, BlockCnt *bl) { · 12 unmodified lines
544 f = fs->f;537 f = fs->f;
545 f->source = ls->source;538 f->source = ls->source;
546 f->maxstacksize = 2; /* registers 0/1 are always valid */539 f->maxstacksize = 2; /* registers 0/1 are always valid */
547 fs->h = luaH_new(L);
548 /* anchor table of constants (to avoid being collected) */
549 sethvalue2s(L, L->top, fs->h);
550 incr_top(L);
551 enterblock(fs, bl, 0);540 enterblock(fs, bl, 0);
552}541}
553 542
@@ -572,9 +561,6 @@ static void close_func (LexState *ls) { · 18 unmodified lines
572 f->sizeupvalues = fs->nups;561 f->sizeupvalues = fs->nups;
573 lua_assert(fs->bl == NULL);562 lua_assert(fs->bl == NULL);
574 ls->fs = fs->prev;563 ls->fs = fs->prev;
575 /* last token read was anchored in defunct function; must re-anchor it */
576 anchor_token(ls);
577 L->top--; /* pop table of constants */
578 luaC_checkGC(L);564 luaC_checkGC(L);
579}565}
580 566
@@ -993,6 +979,7 @@ static UnOpr getunopr (int op) { · 412 unmodified lines
993 switch (op) {979 switch (op) {
994 case TK_NOT: return OPR_NOT;980 case TK_NOT: return OPR_NOT;
995 case '-': return OPR_MINUS;981 case '-': return OPR_MINUS;
982 case '~': return OPR_BNOT;
996 case '#': return OPR_LEN;983 case '#': return OPR_LEN;
997 default: return OPR_NOUNOPR;984 default: return OPR_NOUNOPR;
998 }985 }
@@ -1004,10 +991,15 @@ static BinOpr getbinopr (int op) { · 5 unmodified lines
1004 case '+': return OPR_ADD;991 case '+': return OPR_ADD;
1005 case '-': return OPR_SUB;992 case '-': return OPR_SUB;
1006 case '*': return OPR_MUL;993 case '*': return OPR_MUL;
1007 case '/': return OPR_DIV;
1008 case TK_IDIV: return OPR_IDIV;
1009 case '%': return OPR_MOD;994 case '%': return OPR_MOD;
1010 case '^': return OPR_POW;995 case '^': return OPR_POW;
996 case '/': return OPR_DIV;
997 case TK_IDIV: return OPR_IDIV;
998 case '&': return OPR_BAND;
999 case '|': return OPR_BOR;
1000 case '~': return OPR_BXOR;
1001 case TK_SHL: return OPR_SHL;
1002 case TK_SHR: return OPR_SHR;
1011 case TK_CONCAT: return OPR_CONCAT;1003 case TK_CONCAT: return OPR_CONCAT;
1012 case TK_NE: return OPR_NE;1004 case TK_NE: return OPR_NE;
1013 case TK_EQ: return OPR_EQ;1005 case TK_EQ: return OPR_EQ;
@@ -1026,15 +1018,19 @@ static const struct { · 12 unmodified lines
1026 lu_byte left; /* left priority for each binary operator */1018 lu_byte left; /* left priority for each binary operator */
1027 lu_byte right; /* right priority */1019 lu_byte right; /* right priority */
1028} priority[] = { /* ORDER OPR */1020} priority[] = { /* ORDER OPR */
1029 {6, 6}, {6, 6}, /* '+' '-' */1021 {10, 10}, {10, 10}, /* '+' '-' */
1030 {7, 7}, {7, 7}, {7, 7}, {7, 7}, /* '*' '/' '//' '%' */1022 {11, 11}, {11, 11}, /* '*' '%' */
1031 {10, 9}, {5, 4}, /* ^, .. (right associative) */1023 {14, 13}, /* '^' (right associative) */
1032 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */1024 {11, 11}, {11, 11}, /* '/' '//' */
1033 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */1025 {6, 6}, {4, 4}, {5, 5}, /* '&' '|' '~' */
1034 {2, 2}, {1, 1} /* and, or */1026 {7, 7}, {7, 7}, /* '<<' '>>' */
1027 {9, 8}, /* '..' (right associative) */
1028 {3, 3}, {3, 3}, {3, 3}, /* ==, <, <= */
1029 {3, 3}, {3, 3}, {3, 3}, /* ~=, >, >= */
1030 {2, 2}, {1, 1} /* and, or */
1035};1031};
1036 1032
1037#define UNARY_PRIORITY 8 /* priority for unary operators */1033#define UNARY_PRIORITY 12 /* priority for unary operators */
1038 1034
1039 1035
1040/*1036/*
@@ -1202,7 +1198,7 @@ static void gotostat (LexState *ls, int pc) { · 161 unmodified lines
1202static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {1198static void checkrepeated (FuncState *fs, Labellist *ll, TString *label) {
1203 int i;1199 int i;
1204 for (i = fs->bl->firstlabel; i < ll->n; i++) {1200 for (i = fs->bl->firstlabel; i < ll->n; i++) {
1205 if (luaS_eqstr(label, ll->arr[i].name)) {1201 if (eqstr(label, ll->arr[i].name)) {
1206 const char *msg = luaO_pushfstring(fs->ls->L,1202 const char *msg = luaO_pushfstring(fs->ls->L,
1207 "label " LUA_QS " already defined on line %d",1203 "label " LUA_QS " already defined on line %d",
1208 getstr(label), ll->arr[i].line);1204 getstr(label), ll->arr[i].line);
@@ -1627,11 +1623,14 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, · 418 unmodified lines
1627 LexState lexstate;1623 LexState lexstate;
1628 FuncState funcstate;1624 FuncState funcstate;
1629 Closure *cl = luaF_newLclosure(L, 1); /* create main closure */1625 Closure *cl = luaF_newLclosure(L, 1); /* create main closure */
1630 /* anchor closure (to avoid being collected) */1626 setclLvalue(L, L->top, cl); /* anchor it (to avoid being collected) */
1631 setclLvalue(L, L->top, cl);1627 incr_top(L);
1628 lexstate.h = luaH_new(L); /* create table for scanner */
1629 sethvalue(L, L->top, lexstate.h); /* anchor it */
1632 incr_top(L);1630 incr_top(L);
1633 funcstate.f = cl->l.p = luaF_newproto(L);1631 funcstate.f = cl->l.p = luaF_newproto(L);
1634 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */1632 funcstate.f->source = luaS_new(L, name); /* create and anchor TString */
1633 luaC_objbarrier(L, funcstate.f, funcstate.f->source);
1635 lexstate.buff = buff;1634 lexstate.buff = buff;
1636 lexstate.dyd = dyd;1635 lexstate.dyd = dyd;
1637 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;1636 dyd->actvar.n = dyd->gt.n = dyd->label.n = 0;
@@ -1640,6 +1639,7 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, · 2 unmodified lines
1640 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);1639 lua_assert(!funcstate.prev && funcstate.nups == 1 && !lexstate.fs);
1641 /* all scopes should be correctly finished */1640 /* all scopes should be correctly finished */
1642 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);1641 lua_assert(dyd->actvar.n == 0 && dyd->gt.n == 0 && dyd->label.n == 0);
1643 return cl; /* it's on the stack too */1642 L->top--; /* remove scanner's table */
1643 return cl; /* closure is on the stack, too */
1644}1644}
1645 1645
src/lparser.h+1−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lparser.h,v 1.71 2013/04/16 18:46:28 roberto Exp $2** $Id: lparser.h,v 1.72 2013/08/30 16:01:37 roberto Exp $
3** Lua Parser3** Lua Parser
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -97,7 +97,6 @@ struct BlockCnt; /* defined in lparser.c */ · 91 unmodified lines
97/* state needed to generate code for a given function */97/* state needed to generate code for a given function */
98typedef struct FuncState {98typedef struct FuncState {
99 Proto *f; /* current function header */99 Proto *f; /* current function header */
100 Table *h; /* table to find (and reuse) elements in `k' */
101 struct FuncState *prev; /* enclosing function */100 struct FuncState *prev; /* enclosing function */
102 struct LexState *ls; /* lexical state */101 struct LexState *ls; /* lexical state */
103 struct BlockCnt *bl; /* chain of current blocks */102 struct BlockCnt *bl; /* chain of current blocks */
src/lstate.c+53−32
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstate.c,v 2.99 2012/10/02 17:40:53 roberto Exp $2** $Id: lstate.c,v 2.121 2014/02/18 13:46:26 roberto Exp $
3** Global State3** Global State
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -30,10 +30,6 @@ · 24 unmodified lines
30#define LUAI_GCPAUSE 200 /* 200% */30#define LUAI_GCPAUSE 200 /* 200% */
31#endif31#endif
32 32
33#if !defined(LUAI_GCMAJOR)
34#define LUAI_GCMAJOR 200 /* 200% */
35#endif
36
37#if !defined(LUAI_GCMUL)33#if !defined(LUAI_GCMUL)
38#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */34#define LUAI_GCMUL 200 /* GC runs 'twice the speed' of memory allocation */
39#endif35#endif
@@ -119,6 +115,9 @@ CallInfo *luaE_extendCI (lua_State *L) { · 79 unmodified lines
119}115}
120 116
121 117
118/*
119** free all CallInfo structures not in use by a thread
120*/
122void luaE_freeCI (lua_State *L) {121void luaE_freeCI (lua_State *L) {
123 CallInfo *ci = L->ci;122 CallInfo *ci = L->ci;
124 CallInfo *next = ci->next;123 CallInfo *next = ci->next;
@@ -130,6 +129,22 @@ void luaE_freeCI (lua_State *L) { · 5 unmodified lines
130}129}
131 130
132 131
132/*
133** free half of the CallInfo structures not in use by a thread
134*/
135void luaE_shrinkCI (lua_State *L) {
136 CallInfo *ci = L->ci;
137 while (ci->next != NULL) { /* while there is 'next' */
138 CallInfo *next2 = ci->next->next; /* next's next */
139 if (next2 == NULL) break;
140 luaM_free(L, ci->next); /* remove next */
141 ci->next = next2; /* remove 'next' from the list */
142 next2->previous = ci;
143 ci = next2;
144 }
145}
146
147
133static void stack_init (lua_State *L1, lua_State *L) {148static void stack_init (lua_State *L1, lua_State *L) {
134 int i; CallInfo *ci;149 int i; CallInfo *ci;
135 /* initialize stack array */150 /* initialize stack array */
@@ -163,22 +178,23 @@ static void freestack (lua_State *L) { · 27 unmodified lines
163** Create registry table and its predefined values178** Create registry table and its predefined values
164*/179*/
165static void init_registry (lua_State *L, global_State *g) {180static void init_registry (lua_State *L, global_State *g) {
166 TValue mt;181 TValue temp;
167 /* create registry */182 /* create registry */
168 Table *registry = luaH_new(L);183 Table *registry = luaH_new(L);
169 sethvalue(L, &g->l_registry, registry);184 sethvalue(L, &g->l_registry, registry);
170 luaH_resize(L, registry, LUA_RIDX_LAST, 0);185 luaH_resize(L, registry, LUA_RIDX_LAST, 0);
171 /* registry[LUA_RIDX_MAINTHREAD] = L */186 /* registry[LUA_RIDX_MAINTHREAD] = L */
172 setthvalue(L, &mt, L);187 setthvalue(L, &temp, L); /* temp = L */
173 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt);188 luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp);
174 /* registry[LUA_RIDX_GLOBALS] = table of globals */189 /* registry[LUA_RIDX_GLOBALS] = table of globals */
175 sethvalue(L, &mt, luaH_new(L));190 sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */
176 luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt);191 luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp);
177}192}
178 193
179 194
180/*195/*
181** open parts of the state that may cause memory-allocation errors196** open parts of the state that may cause memory-allocation errors.
197** ('g->version' != NULL flags that the state was completely build)
182*/198*/
183static void f_luaopen (lua_State *L, void *ud) {199static void f_luaopen (lua_State *L, void *ud) {
184 global_State *g = G(L);200 global_State *g = G(L);
@@ -190,20 +206,23 @@ static void f_luaopen (lua_State *L, void *ud) { · 5 unmodified lines
190 luaX_init(L);206 luaX_init(L);
191 /* pre-create memory-error message */207 /* pre-create memory-error message */
192 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);208 g->memerrmsg = luaS_newliteral(L, MEMERRMSG);
193 luaS_fix(g->memerrmsg); /* it should never be collected */209 luaC_fix(L, obj2gco(g->memerrmsg)); /* it should never be collected */
194 g->gcrunning = 1; /* allow gc */210 g->gcrunning = 1; /* allow gc */
211 g->version = lua_version(NULL);
212 luai_userstateopen(L);
195}213}
196 214
197 215
198/*216/*
199** preinitialize a state with consistent values without allocating217** preinitialize a thread with consistent values without allocating
200** any memory (to avoid errors)218** any memory (to avoid errors)
201*/219*/
202static void preinit_state (lua_State *L, global_State *g) {220static void preinit_thread (lua_State *L, global_State *g) {
203 G(L) = g;221 G(L) = g;
204 L->stack = NULL;222 L->stack = NULL;
205 L->ci = NULL;223 L->ci = NULL;
206 L->stacksize = 0;224 L->stacksize = 0;
225 L->twups = L; /* thread has no upvalues */
207 L->errorJmp = NULL;226 L->errorJmp = NULL;
208 L->nCcalls = 0;227 L->nCcalls = 0;
209 L->hook = NULL;228 L->hook = NULL;
@@ -222,6 +241,8 @@ static void close_state (lua_State *L) { · 12 unmodified lines
222 global_State *g = G(L);241 global_State *g = G(L);
223 luaF_close(L, L->stack); /* close all upvalues for this thread */242 luaF_close(L, L->stack); /* close all upvalues for this thread */
224 luaC_freeallobjects(L); /* collect all objects */243 luaC_freeallobjects(L); /* collect all objects */
244 if (g->version) /* closing a fully built state? */
245 luai_userstateclose(L);
225 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);246 luaM_freearray(L, G(L)->strt.hash, G(L)->strt.size);
226 luaZ_freebuffer(L, &g->buff);247 luaZ_freebuffer(L, &g->buff);
227 freestack(L);248 freestack(L);
@@ -231,13 +252,20 @@ static void close_state (lua_State *L) { · 3 unmodified lines
231 252
232 253
233LUA_API lua_State *lua_newthread (lua_State *L) {254LUA_API lua_State *lua_newthread (lua_State *L) {
255 global_State *g = G(L);
234 lua_State *L1;256 lua_State *L1;
235 lua_lock(L);257 lua_lock(L);
236 luaC_checkGC(L);258 luaC_checkGC(L);
237 L1 = &luaC_newobj(L, LUA_TTHREAD, sizeof(LX), NULL, offsetof(LX, l))->th;259 /* create new thread */
260 L1 = &cast(LX *, luaM_newobject(L, LUA_TTHREAD, sizeof(LX)))->l;
261 L1->marked = luaC_white(g);
262 L1->tt = LUA_TTHREAD;
263 /* link it on list 'allgc' */
264 L1->next = g->allgc;
265 g->allgc = obj2gco(L1);
238 setthvalue(L, L->top, L1);266 setthvalue(L, L->top, L1);
239 api_incr_top(L);267 api_incr_top(L);
240 preinit_state(L1, G(L));268 preinit_thread(L1, g);
241 L1->hookmask = L->hookmask;269 L1->hookmask = L->hookmask;
242 L1->basehookcount = L->basehookcount;270 L1->basehookcount = L->basehookcount;
243 L1->hook = L->hook;271 L1->hook = L->hook;
@@ -269,36 +297,32 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 25 unmodified lines
269 g = &l->g;297 g = &l->g;
270 L->next = NULL;298 L->next = NULL;
271 L->tt = LUA_TTHREAD;299 L->tt = LUA_TTHREAD;
272 g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT);300 g->currentwhite = bitmask(WHITE0BIT);
273 L->marked = luaC_white(g);301 L->marked = luaC_white(g);
274 g->gckind = KGC_NORMAL;302 preinit_thread(L, g);
275 preinit_state(L, g);
276 g->frealloc = f;303 g->frealloc = f;
277 g->ud = ud;304 g->ud = ud;
278 g->mainthread = L;305 g->mainthread = L;
279 g->seed = makeseed(L);306 g->seed = makeseed(L);
280 g->uvhead.u.l.prev = &g->uvhead;
281 g->uvhead.u.l.next = &g->uvhead;
282 g->gcrunning = 0; /* no GC while building state */307 g->gcrunning = 0; /* no GC while building state */
283 g->GCestimate = 0;308 g->GCestimate = 0;
284 g->strt.size = 0;309 g->strt.size = g->strt.nuse = 0;
285 g->strt.nuse = 0;
286 g->strt.hash = NULL;310 g->strt.hash = NULL;
287 setnilvalue(&g->l_registry);311 setnilvalue(&g->l_registry);
288 luaZ_initbuffer(L, &g->buff);312 luaZ_initbuffer(L, &g->buff);
289 g->panic = NULL;313 g->panic = NULL;
290 g->version = lua_version(NULL);314 g->version = NULL;
291 g->gcstate = GCSpause;315 g->gcstate = GCSpause;
292 g->allgc = NULL;316 g->gckind = KGC_NORMAL;
293 g->finobj = NULL;317 g->allgc = g->finobj = g->tobefnz = g->fixedgc = NULL;
294 g->tobefnz = NULL;318 g->sweepgc = NULL;
295 g->sweepgc = g->sweepfin = NULL;
296 g->gray = g->grayagain = NULL;319 g->gray = g->grayagain = NULL;
297 g->weak = g->ephemeron = g->allweak = NULL;320 g->weak = g->ephemeron = g->allweak = NULL;
321 g->twups = NULL;
298 g->totalbytes = sizeof(LG);322 g->totalbytes = sizeof(LG);
299 g->GCdebt = 0;323 g->GCdebt = 0;
324 g->gcfinnum = 0;
300 g->gcpause = LUAI_GCPAUSE;325 g->gcpause = LUAI_GCPAUSE;
301 g->gcmajorinc = LUAI_GCMAJOR;
302 g->gcstepmul = LUAI_GCMUL;326 g->gcstepmul = LUAI_GCMUL;
303 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;327 for (i=0; i < LUA_NUMTAGS; i++) g->mt[i] = NULL;
304 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {328 if (luaD_rawrunprotected(L, f_luaopen, NULL) != LUA_OK) {
@@ -306,8 +330,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 1 unmodified line
306 close_state(L);330 close_state(L);
307 L = NULL;331 L = NULL;
308 }332 }
309 else
310 luai_userstateopen(L);
311 return L;333 return L;
312}334}
313 335
@@ -315,7 +337,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { · 1 unmodified line
315LUA_API void lua_close (lua_State *L) {337LUA_API void lua_close (lua_State *L) {
316 L = G(L)->mainthread; /* only the main thread can be closed */338 L = G(L)->mainthread; /* only the main thread can be closed */
317 lua_lock(L);339 lua_lock(L);
318 luai_userstateclose(L);
319 close_state(L);340 close_state(L);
320}341}
321 342
src/lstate.h+19−30
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstate.h,v 2.82 2012/07/02 13:37:04 roberto Exp $2** $Id: lstate.h,v 2.102 2014/02/18 13:46:26 roberto Exp $
3** Global State3** Global State
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -16,25 +16,16 @@ · 10 unmodified lines
16 16
17/*17/*
18 18
19** Some notes about garbage-collected objects: All objects in Lua must19** Some notes about garbage-collected objects: All objects in Lua must
20** be kept somehow accessible until being freed.20** be kept somehow accessible until being freed, so all objects always
21** belong to one (and only one) of these lists, using field 'next' of
22** the 'CommonHeader' for the link:
21**23**
22** Lua keeps most objects linked in list g->allgc. The link uses field24** allgc: all objects not marked for finalization;
23** 'next' of the CommonHeader.25** finobj: all objects marked for finalization;
24**26** tobefnz: all objects ready to be finalized;
25** Strings are kept in several lists headed by the array g->strt.hash.27** fixedgc: all objects that are not to be collected (currently
26**28** only small strings, such as reserved words).
27** Open upvalues are not subject to independent garbage collection. They
28** are collected together with their respective threads. Lua keeps a
29** double-linked list with all open upvalues (g->uvhead) so that it can
30** mark objects referred by them. (They are always gray, so they must
31** be remarked in the atomic step. Usually their contents would be marked
32** when traversing the respective threads, but the thread may already be
33** dead, while the upvalue is still accessible through closures.)
34**
35** Objects with finalizers are kept in the list g->finobj.
36**
37** The list g->tobefnz links all objects being finalized.
38 29
39*/30*/
40 31
@@ -53,12 +44,11 @@ struct lua_longjmp; /* defined in ldo.c */ · 12 unmodified lines
53/* kinds of Garbage Collection */44/* kinds of Garbage Collection */
54#define KGC_NORMAL 045#define KGC_NORMAL 0
55#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */46#define KGC_EMERGENCY 1 /* gc was forced by an allocation failure */
56#define KGC_GEN 2 /* generational collection */
57 47
58 48
59typedef struct stringtable {49typedef struct stringtable {
60 GCObject **hash;50 TString **hash;
61 lu_int32 nuse; /* number of elements */51 int nuse; /* number of elements */
62 int size;52 int size;
63} stringtable;53} stringtable;
64 54
@@ -123,21 +113,20 @@ typedef struct global_State { · 58 unmodified lines
123 lu_byte gcstate; /* state of garbage collector */113 lu_byte gcstate; /* state of garbage collector */
124 lu_byte gckind; /* kind of GC running */114 lu_byte gckind; /* kind of GC running */
125 lu_byte gcrunning; /* true if GC is running */115 lu_byte gcrunning; /* true if GC is running */
126 int sweepstrgc; /* position of sweep in `strt' */
127 GCObject *allgc; /* list of all collectable objects */116 GCObject *allgc; /* list of all collectable objects */
117 GCObject **sweepgc; /* current position of sweep in list */
128 GCObject *finobj; /* list of collectable objects with finalizers */118 GCObject *finobj; /* list of collectable objects with finalizers */
129 GCObject **sweepgc; /* current position of sweep in list 'allgc' */
130 GCObject **sweepfin; /* current position of sweep in list 'finobj' */
131 GCObject *gray; /* list of gray objects */119 GCObject *gray; /* list of gray objects */
132 GCObject *grayagain; /* list of objects to be traversed atomically */120 GCObject *grayagain; /* list of objects to be traversed atomically */
133 GCObject *weak; /* list of tables with weak values */121 GCObject *weak; /* list of tables with weak values */
134 GCObject *ephemeron; /* list of ephemeron tables (weak keys) */122 GCObject *ephemeron; /* list of ephemeron tables (weak keys) */
135 GCObject *allweak; /* list of all-weak tables */123 GCObject *allweak; /* list of all-weak tables */
136 GCObject *tobefnz; /* list of userdata to be GC */124 GCObject *tobefnz; /* list of userdata to be GC */
137 UpVal uvhead; /* head of double-linked list of all open upvalues */125 GCObject *fixedgc; /* list of objects not to be collected */
126 struct lua_State *twups; /* list of threads with open upvalues */
138 Mbuffer buff; /* temporary buffer for string concatenation */127 Mbuffer buff; /* temporary buffer for string concatenation */
128 unsigned int gcfinnum; /* number of finalizers to call in each GC step */
139 int gcpause; /* size of pause between successive GCs */129 int gcpause; /* size of pause between successive GCs */
140 int gcmajorinc; /* pause between major collections (only in gen. mode) */
141 int gcstepmul; /* GC `granularity' */130 int gcstepmul; /* GC `granularity' */
142 lua_CFunction panic; /* to be called in unprotected errors */131 lua_CFunction panic; /* to be called in unprotected errors */
143 struct lua_State *mainthread;132 struct lua_State *mainthread;
@@ -168,8 +157,9 @@ struct lua_State { · 24 unmodified lines
168 int basehookcount;157 int basehookcount;
169 int hookcount;158 int hookcount;
170 lua_Hook hook;159 lua_Hook hook;
171 GCObject *openupval; /* list of open upvalues in this stack */160 UpVal *openupval; /* list of open upvalues in this stack */
172 GCObject *gclist;161 GCObject *gclist;
162 struct lua_State *twups; /* list of threads with open upvalues */
173 struct lua_longjmp *errorJmp; /* current error recover point */163 struct lua_longjmp *errorJmp; /* current error recover point */
174 ptrdiff_t errfunc; /* current error handling function (stack index) */164 ptrdiff_t errfunc; /* current error handling function (stack index) */
175 CallInfo base_ci; /* CallInfo for first level (C calling Lua) */165 CallInfo base_ci; /* CallInfo for first level (C calling Lua) */
@@ -189,7 +179,6 @@ union GCObject { · 13 unmodified lines
189 union Closure cl;179 union Closure cl;
190 struct Table h;180 struct Table h;
191 struct Proto p;181 struct Proto p;
192 struct UpVal uv;
193 struct lua_State th; /* thread */182 struct lua_State th; /* thread */
194};183};
195 184
@@ -208,7 +197,6 @@ union GCObject { · 12 unmodified lines
208 check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))197 check_exp(novariant((o)->gch.tt) == LUA_TFUNCTION, &((o)->cl))
209#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))198#define gco2t(o) check_exp((o)->gch.tt == LUA_TTABLE, &((o)->h))
210#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))199#define gco2p(o) check_exp((o)->gch.tt == LUA_TPROTO, &((o)->p))
211#define gco2uv(o) check_exp((o)->gch.tt == LUA_TUPVAL, &((o)->uv))
212#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))200#define gco2th(o) check_exp((o)->gch.tt == LUA_TTHREAD, &((o)->th))
213 201
214/* macro to convert any Lua object into a GCObject */202/* macro to convert any Lua object into a GCObject */
@@ -222,6 +210,7 @@ LUAI_FUNC void luaE_setdebt (global_State *g, l_mem debt); · 7 unmodified lines
222LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);210LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1);
223LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);211LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L);
224LUAI_FUNC void luaE_freeCI (lua_State *L);212LUAI_FUNC void luaE_freeCI (lua_State *L);
213LUAI_FUNC void luaE_shrinkCI (lua_State *L);
225 214
226 215
227#endif216#endif
src/lstring.c+46−55
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstring.c,v 2.27 2013/06/19 14:27:00 roberto Exp $2** $Id: lstring.c,v 2.38 2014/03/19 18:51:42 roberto Exp $
3** String table (keeps all strings handled by Lua)3** String table (keeps all strings handled by Lua)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -12,12 +12,15 @@ · 6 unmodified lines
12 12
13#include "lua.h"13#include "lua.h"
14 14
15#include "ldebug.h"
16#include "ldo.h"
15#include "lmem.h"17#include "lmem.h"
16#include "lobject.h"18#include "lobject.h"
17#include "lstate.h"19#include "lstate.h"
18#include "lstring.h"20#include "lstring.h"
19 21
20 22
23
21/*24/*
22** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to25** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a string to
23** compute its hash26** compute its hash
@@ -39,15 +42,6 @@ int luaS_eqlngstr (TString *a, TString *b) { · 15 unmodified lines
39}42}
40 43
41 44
42/*
43** equality for strings
44*/
45int luaS_eqstr (TString *a, TString *b) {
46 return (a->tsv.tt == b->tsv.tt) &&
47 (a->tsv.tt == LUA_TSHRSTR ? eqshrstr(a, b) : luaS_eqlngstr(a, b));
48}
49
50
51unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {45unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) {
52 unsigned int h = seed ^ cast(unsigned int, l);46 unsigned int h = seed ^ cast(unsigned int, l);
53 size_t l1;47 size_t l1;
@@ -64,43 +58,41 @@ unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { · 10 unmodified lines
64void luaS_resize (lua_State *L, int newsize) {58void luaS_resize (lua_State *L, int newsize) {
65 int i;59 int i;
66 stringtable *tb = &G(L)->strt;60 stringtable *tb = &G(L)->strt;
67 /* cannot resize while GC is traversing strings */61 if (newsize > tb->size) { /* grow table if needed */
68 luaC_runtilstate(L, ~bitmask(GCSsweepstring));62 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
69 if (newsize > tb->size) {63 for (i = tb->size; i < newsize; i++)
70 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);64 tb->hash[i] = NULL;
71 for (i = tb->size; i < newsize; i++) tb->hash[i] = NULL;
72 }65 }
73 /* rehash */66 for (i = 0; i < tb->size; i++) { /* rehash */
74 for (i=0; i<tb->size; i++) {67 TString *p = tb->hash[i];
75 GCObject *p = tb->hash[i];
76 tb->hash[i] = NULL;68 tb->hash[i] = NULL;
77 while (p) { /* for each node in the list */69 while (p) { /* for each node in the list */
78 GCObject *next = gch(p)->next; /* save next */70 TString *hnext = p->tsv.hnext; /* save next */
79 unsigned int h = lmod(gco2ts(p)->hash, newsize); /* new position */71 unsigned int h = lmod(p->tsv.hash, newsize); /* new position */
80 gch(p)->next = tb->hash[h]; /* chain it */72 p->tsv.hnext = tb->hash[h]; /* chain it */
81 tb->hash[h] = p;73 tb->hash[h] = p;
82 resetoldbit(p); /* see MOVE OLD rule */74 p = hnext;
83 p = next;
84 }75 }
85 }76 }
86 if (newsize < tb->size) {77 if (newsize < tb->size) { /* shrink table if needed */
87 /* shrinking slice must be empty */78 /* vanishing slice should be empty */
88 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);79 lua_assert(tb->hash[newsize] == NULL && tb->hash[tb->size - 1] == NULL);
89 luaM_reallocvector(L, tb->hash, tb->size, newsize, GCObject *);80 luaM_reallocvector(L, tb->hash, tb->size, newsize, TString *);
90 }81 }
91 tb->size = newsize;82 tb->size = newsize;
92}83}
93 84
94 85
86
95/*87/*
96** creates a new string object88** creates a new string object
97*/89*/
98static TString *createstrobj (lua_State *L, const char *str, size_t l,90static TString *createstrobj (lua_State *L, const char *str, size_t l,
99 int tag, unsigned int h, GCObject **list) {91 int tag, unsigned int h) {
100 TString *ts;92 TString *ts;
101 size_t totalsize; /* total size of TString object */93 size_t totalsize; /* total size of TString object */
102 totalsize = sizeof(TString) + ((l + 1) * sizeof(char));94 totalsize = sizeof(TString) + ((l + 1) * sizeof(char));
103 ts = &luaC_newobj(L, tag, totalsize, list, 0)->ts;95 ts = &luaC_newobj(L, tag, totalsize)->ts;
104 ts->tsv.len = l;96 ts->tsv.len = l;
105 ts->tsv.hash = h;97 ts->tsv.hash = h;
106 ts->tsv.extra = 0;98 ts->tsv.extra = 0;
@@ -110,20 +102,13 @@ static TString *createstrobj (lua_State *L, const char *str, size_t l, · 3 unmodified lines
110}102}
111 103
112 104
113/*105LUAI_FUNC void luaS_remove (lua_State *L, TString *ts) {
114** creates a new short string, inserting it into string table
115*/
116static TString *newshrstr (lua_State *L, const char *str, size_t l,
117 unsigned int h) {
118 GCObject **list; /* (pointer to) list where it will be inserted */
119 stringtable *tb = &G(L)->strt;106 stringtable *tb = &G(L)->strt;
120 TString *s;107 TString **p = &tb->hash[lmod(ts->tsv.hash, tb->size)];
121 if (tb->nuse >= cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)108 while (*p != ts) /* find previous element */
122 luaS_resize(L, tb->size*2); /* too crowded */109 p = &(*p)->tsv.hnext;
123 list = &tb->hash[lmod(h, tb->size)];110 *p = (*p)->tsv.hnext; /* remove element from its list */
124 s = createstrobj(L, str, l, LUA_TSHRSTR, h, list);111 tb->nuse--;
125 tb->nuse++;
126 return s;
127}112}
128 113
129 114
@@ -131,22 +116,28 @@ static TString *newshrstr (lua_State *L, const char *str, size_t l, · 1 unmodified line
131** checks whether short string exists and reuses it or creates a new one116** checks whether short string exists and reuses it or creates a new one
132*/117*/
133static TString *internshrstr (lua_State *L, const char *str, size_t l) {118static TString *internshrstr (lua_State *L, const char *str, size_t l) {
134 GCObject *o;119 TString *ts;
135 global_State *g = G(L);120 global_State *g = G(L);
136 unsigned int h = luaS_hash(str, l, g->seed);121 unsigned int h = luaS_hash(str, l, g->seed);
137 for (o = g->strt.hash[lmod(h, g->strt.size)];122 TString **list = &g->strt.hash[lmod(h, g->strt.size)];
138 o != NULL;123 for (ts = *list; ts != NULL; ts = ts->tsv.hnext) {
139 o = gch(o)->next) {124 if (l == ts->tsv.len &&
140 TString *ts = rawgco2ts(o);
141 if (h == ts->tsv.hash &&
142 l == ts->tsv.len &&
143 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {125 (memcmp(str, getstr(ts), l * sizeof(char)) == 0)) {
144 if (isdead(G(L), o)) /* string is dead (but was not collected yet)? */126 /* found! */
145 changewhite(o); /* resurrect it */127 if (isdead(g, obj2gco(ts))) /* dead (but not collected yet)? */
128 changewhite(obj2gco(ts)); /* resurrect it */
146 return ts;129 return ts;
147 }130 }
148 }131 }
149 return newshrstr(L, str, l, h); /* not found; create a new string */132 if (g->strt.nuse >= g->strt.size && g->strt.size <= MAX_INT/2) {
133 luaS_resize(L, g->strt.size * 2);
134 list = &g->strt.hash[lmod(h, g->strt.size)]; /* recompute with new size */
135 }
136 ts = createstrobj(L, str, l, LUA_TSHRSTR, h);
137 ts->tsv.hnext = *list;
138 *list = ts;
139 g->strt.nuse++;
140 return ts;
150}141}
151 142
152 143
@@ -159,7 +150,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { · 6 unmodified lines
159 else {150 else {
160 if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))151 if (l + 1 > (MAX_SIZE - sizeof(TString))/sizeof(char))
161 luaM_toobig(L);152 luaM_toobig(L);
162 return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed, NULL);153 return createstrobj(L, str, l, LUA_TLNGSTR, G(L)->seed);
163 }154 }
164}155}
165 156
@@ -172,14 +163,14 @@ TString *luaS_new (lua_State *L, const char *str) { · 6 unmodified lines
172}163}
173 164
174 165
175Udata *luaS_newudata (lua_State *L, size_t s, Table *e) {166Udata *luaS_newudata (lua_State *L, size_t s) {
176 Udata *u;167 Udata *u;
177 if (s > MAX_SIZE - sizeof(Udata))168 if (s > MAX_SIZE - sizeof(Udata))
178 luaM_toobig(L);169 luaM_toobig(L);
179 u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s, NULL, 0)->u;170 u = &luaC_newobj(L, LUA_TUSERDATA, sizeof(Udata) + s)->u;
180 u->uv.len = s;171 u->uv.len = s;
181 u->uv.metatable = NULL;172 u->uv.metatable = NULL;
182 u->uv.env = e;173 setuservalue(L, u, luaO_nilobject);
183 return u;174 return u;
184}175}
185 176
src/lstring.h+3−5
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstring.h,v 1.49 2012/02/01 21:57:15 roberto Exp $2** $Id: lstring.h,v 1.54 2014/03/19 18:51:42 roberto Exp $
3** String table (keep all strings handled by Lua)3** String table (keep all strings handled by Lua)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -19,8 +19,6 @@ · 13 unmodified lines
19#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \19#define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \
20 (sizeof(s)/sizeof(char))-1))20 (sizeof(s)/sizeof(char))-1))
21 21
22#define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
23
24 22
25/*23/*
26** test whether a string is a reserved word24** test whether a string is a reserved word
@@ -36,9 +34,9 @@ · 9 unmodified lines
36 34
37LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);35LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed);
38LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);36LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b);
39LUAI_FUNC int luaS_eqstr (TString *a, TString *b);
40LUAI_FUNC void luaS_resize (lua_State *L, int newsize);37LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
41LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);38LUAI_FUNC void luaS_remove (lua_State *L, TString *ts);
39LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s);
42LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);40LUAI_FUNC TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
43LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);41LUAI_FUNC TString *luaS_new (lua_State *L, const char *str);
44 42
src/lstrlib.c+222−5
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lstrlib.c,v 1.182 2013/06/20 15:06:51 roberto Exp $2** $Id: lstrlib.c,v 1.189 2014/03/21 14:26:44 roberto Exp $
3** Standard library for string operations and pattern-matching3** Standard library for string operations and pattern-matching
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -116,7 +116,7 @@ static int str_rep (lua_State *L) { · 110 unmodified lines
116 lua_Integer n = luaL_checkinteger(L, 2);116 lua_Integer n = luaL_checkinteger(L, 2);
117 const char *sep = luaL_optlstring(L, 3, "", &lsep);117 const char *sep = luaL_optlstring(L, 3, "", &lsep);
118 if (n <= 0) lua_pushliteral(L, "");118 if (n <= 0) lua_pushliteral(L, "");
119 else if (l + lsep < l || l + lsep >= MAXSIZE / n) /* may overflow? */119 else if (l + lsep < l || l + lsep > MAXSIZE / n) /* may overflow? */
120 return luaL_error(L, "resulting string too large");120 return luaL_error(L, "resulting string too large");
121 else {121 else {
122 size_t totallen = n * l + (n - 1) * lsep;122 size_t totallen = n * l + (n - 1) * lsep;
@@ -124,8 +124,9 @@ static int str_rep (lua_State *L) { · 1 unmodified line
124 char *p = luaL_buffinitsize(L, &b, totallen);124 char *p = luaL_buffinitsize(L, &b, totallen);
125 while (n-- > 1) { /* first n-1 copies (followed by separator) */125 while (n-- > 1) { /* first n-1 copies (followed by separator) */
126 memcpy(p, s, l * sizeof(char)); p += l;126 memcpy(p, s, l * sizeof(char)); p += l;
127 if (lsep > 0) { /* avoid empty 'memcpy' (may be expensive) */127 if (lsep > 0) { /* empty 'memcpy' is not that cheap */
128 memcpy(p, sep, lsep * sizeof(char)); p += lsep;128 memcpy(p, sep, lsep * sizeof(char));
129 p += lsep;
129 }130 }
130 }131 }
131 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */132 memcpy(p, s, l * sizeof(char)); /* last copy (not followed by separator) */
@@ -178,10 +179,11 @@ static int writer (lua_State *L, const void *b, size_t size, void *B) { · 46 unmodified lines
178 179
179static int str_dump (lua_State *L) {180static int str_dump (lua_State *L) {
180 luaL_Buffer b;181 luaL_Buffer b;
182 int strip = lua_toboolean(L, 2);
181 luaL_checktype(L, 1, LUA_TFUNCTION);183 luaL_checktype(L, 1, LUA_TFUNCTION);
182 lua_settop(L, 1);184 lua_settop(L, 1);
183 luaL_buffinit(L,&b);185 luaL_buffinit(L,&b);
184 if (lua_dump(L, writer, &b) != 0)186 if (lua_dump(L, writer, &b, strip) != 0)
185 return luaL_error(L, "unable to dump given function");187 return luaL_error(L, "unable to dump given function");
186 luaL_pushresult(&b);188 luaL_pushresult(&b);
187 return 1;189 return 1;
@@ -938,6 +940,217 @@ static int str_format (lua_State *L) { · 750 unmodified lines
938/* }====================================================== */940/* }====================================================== */
939 941
940 942
943/*
944** {======================================================
945** PACK/UNPACK
946** =======================================================
947*/
948
949/* maximum size for the binary representation of an integer */
950#define MAXINTSIZE 8
951
952
953/* number of bits in a character */
954#define NB CHAR_BIT
955
956/* mask for one character (NB ones) */
957#define MC (((lua_Integer)1 << NB) - 1)
958
959/* mask for one character without sign ((NB - 1) ones) */
960#define SM (((lua_Integer)1 << (NB - 1)) - 1)
961
962
963#define SZINT ((int)sizeof(lua_Integer))
964
965
966static union {
967 int dummy;
968 char little; /* true iff machine is little endian */
969} const nativeendian = {1};
970
971
972static int getendian (lua_State *L, int arg) {
973 const char *endian = luaL_optstring(L, arg,
974 (nativeendian.little ? "l" : "b"));
975 if (*endian == 'n') /* native? */
976 return nativeendian.little;
977 luaL_argcheck(L, *endian == 'l' || *endian == 'b', arg,
978 "endianess must be 'l'/'b'/'n'");
979 return (*endian == 'l');
980}
981
982
983static int getintsize (lua_State *L, int arg) {
984 int size = luaL_optint(L, arg, 0);
985 if (size == 0) size = SZINT;
986 luaL_argcheck(L, 1 <= size && size <= MAXINTSIZE, arg,
987 "integer size out of valid range");
988 return size;
989}
990
991
992static int packint (char *buff, lua_Integer n, int littleendian, int size) {
993 int i;
994 if (littleendian) {
995 for (i = 0; i < size - 1; i++) {
996 buff[i] = (n & MC);
997 n >>= NB;
998 }
999 }
1000 else {
1001 for (i = size - 1; i > 0; i--) {
1002 buff[i] = (n & MC);
1003 n >>= NB;
1004 }
1005 }
1006 buff[i] = (n & MC); /* last byte */
1007 /* test for overflow: OK if there are only zeros left in higher bytes,
1008 or if there are only ones left and packed number is negative (signal
1009 bit, the higher bit in last byte, is one) */
1010 return ((n & ~MC) == 0 || (n | SM) == ~(lua_Integer)0);
1011}
1012
1013
1014static int packint_l (lua_State *L) {
1015 char buff[MAXINTSIZE];
1016 lua_Integer n = luaL_checkinteger(L, 1);
1017 int size = getintsize(L, 2);
1018 int endian = getendian(L, 3);
1019 if (packint(buff, n, endian, size))
1020 lua_pushlstring(L, buff, size);
1021 else
1022 luaL_error(L, "integer does not fit into given size (%d)", size);
1023 return 1;
1024}
1025
1026
1027/* mask to check higher-order byte in a Lua integer */
1028#define HIGHERBYTE (MC << (NB * (SZINT - 1)))
1029
1030/* mask to check higher-order byte + signal bit of next (lower) byte */
1031#define HIGHERBYTE1 (HIGHERBYTE | (HIGHERBYTE >> 1))
1032
1033static int unpackint (const char *buff, lua_Integer *res,
1034 int littleendian, int size) {
1035 lua_Integer n = 0;
1036 int i;
1037 for (i = 0; i < size; i++) {
1038 if (i >= SZINT) { /* will throw away a byte? */
1039 /* check for overflow: it is OK to throw away leading zeros for a
1040 positive number, leading ones for a negative number, and a
1041 leading zero byte to allow unsigned integers with a 1 in
1042 its "signal bit" */
1043 if (!((n & HIGHERBYTE1) == 0 || /* zeros for positive number */
1044 (n & HIGHERBYTE1) == HIGHERBYTE1 || /* ones for negative number */
1045 ((n & HIGHERBYTE) == 0 && i == size - 1))) /* leading zero */
1046 return 0; /* overflow */
1047 }
1048 n <<= NB;
1049 n |= (lua_Integer)(unsigned char)buff[littleendian ? size - 1 - i : i];
1050 }
1051 if (size < SZINT) { /* need sign extension? */
1052 lua_Integer mask = (~(lua_Integer)0) << (size*NB - 1);
1053 if (n & mask) /* negative value? */
1054 n |= mask; /* signal extension */
1055 }
1056 *res = n;
1057 return 1;
1058}
1059
1060
1061static int unpackint_l (lua_State *L) {
1062 lua_Integer res;
1063 size_t len;
1064 const char *s = luaL_checklstring(L, 1, &len);
1065 lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
1066 int size = getintsize(L, 3);
1067 int endian = getendian(L, 4);
1068 luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
1069 "string too short");
1070 if(unpackint(s + pos - 1, &res, endian, size))
1071 lua_pushinteger(L, res);
1072 else
1073 luaL_error(L, "result does not fit into a Lua integer");
1074 return 1;
1075}
1076
1077
1078static void correctendianess (lua_State *L, char *b, int size, int endianarg) {
1079 int endian = getendian(L, endianarg);
1080 if (endian != nativeendian.little) { /* not native endianess? */
1081 int i = 0;
1082 while (i < --size) {
1083 char temp = b[i];
1084 b[i++] = b[size];
1085 b[size] = temp;
1086 }
1087 }
1088}
1089
1090
1091static int getfloatsize (lua_State *L, int arg) {
1092 const char *size = luaL_optstring(L, arg, "n");
1093 if (*size == 'n') return sizeof(lua_Number);
1094 luaL_argcheck(L, *size == 'd' || *size == 'f', arg,
1095 "size must be 'f'/'d'/'n'");
1096 return (*size == 'd' ? sizeof(double) : sizeof(float));
1097}
1098
1099
1100static int packfloat_l (lua_State *L) {
1101 float f; double d;
1102 char *pn; /* pointer to number */
1103 lua_Number n = luaL_checknumber(L, 1);
1104 int size = getfloatsize(L, 2);
1105 if (size == sizeof(lua_Number))
1106 pn = (char*)&n;
1107 else if (size == sizeof(float)) {
1108 f = (float)n;
1109 pn = (char*)&f;
1110 }
1111 else { /* native lua_Number may be neither float nor double */
1112 lua_assert(size == sizeof(double));
1113 d = (double)n;
1114 pn = (char*)&d;
1115 }
1116 correctendianess(L, pn, size, 3);
1117 lua_pushlstring(L, pn, size);
1118 return 1;
1119}
1120
1121
1122static int unpackfloat_l (lua_State *L) {
1123 lua_Number res;
1124 size_t len;
1125 const char *s = luaL_checklstring(L, 1, &len);
1126 lua_Integer pos = posrelat(luaL_optinteger(L, 2, 1), len);
1127 int size = getfloatsize(L, 3);
1128 luaL_argcheck(L, 1 <= pos && (size_t)pos + size - 1 <= len, 1,
1129 "string too short");
1130 if (size == sizeof(lua_Number)) {
1131 memcpy(&res, s + pos - 1, size);
1132 correctendianess(L, (char*)&res, size, 4);
1133 }
1134 else if (size == sizeof(float)) {
1135 float f;
1136 memcpy(&f, s + pos - 1, size);
1137 correctendianess(L, (char*)&f, size, 4);
1138 res = (lua_Number)f;
1139 }
1140 else { /* native lua_Number may be neither float nor double */
1141 double d;
1142 lua_assert(size == sizeof(double));
1143 memcpy(&d, s + pos - 1, size);
1144 correctendianess(L, (char*)&d, size, 4);
1145 res = (lua_Number)d;
1146 }
1147 lua_pushnumber(L, res);
1148 return 1;
1149}
1150
1151/* }====================================================== */
1152
1153
941static const luaL_Reg strlib[] = {1154static const luaL_Reg strlib[] = {
942 {"byte", str_byte},1155 {"byte", str_byte},
943 {"char", str_char},1156 {"char", str_char},
@@ -953,6 +1166,10 @@ static const luaL_Reg strlib[] = { · 9 unmodified lines
953 {"reverse", str_reverse},1166 {"reverse", str_reverse},
954 {"sub", str_sub},1167 {"sub", str_sub},
955 {"upper", str_upper},1168 {"upper", str_upper},
1169 {"packfloat", packfloat_l},
1170 {"packint", packint_l},
1171 {"unpackfloat", unpackfloat_l},
1172 {"unpackint", unpackint_l},
956 {NULL, NULL}1173 {NULL, NULL}
957};1174};
958 1175
src/ltable.c+47−27
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltable.c,v 2.78 2013/06/20 15:02:49 roberto Exp $2** $Id: ltable.c,v 2.84 2014/01/27 13:34:32 roberto Exp $
3** Lua tables (hash)3** Lua tables (hash)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -79,7 +79,7 @@ · 73 unmodified lines
79 79
80static const Node dummynode_ = {80static const Node dummynode_ = {
81 {NILCONSTANT}, /* value */81 {NILCONSTANT}, /* value */
82 {{NILCONSTANT, NULL}} /* key */82 {{NILCONSTANT, 0}} /* key */
83};83};
84 84
85 85
@@ -158,6 +158,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { · 72 unmodified lines
158 if (0 < i && i <= t->sizearray) /* is `key' inside array part? */158 if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
159 return i-1; /* yes; that's the index (corrected to C) */159 return i-1; /* yes; that's the index (corrected to C) */
160 else {160 else {
161 int nx;
161 Node *n = mainposition(t, key);162 Node *n = mainposition(t, key);
162 for (;;) { /* check whether `key' is somewhere in the chain */163 for (;;) { /* check whether `key' is somewhere in the chain */
163 /* key may be dead already, but it is ok to use it in `next' */164 /* key may be dead already, but it is ok to use it in `next' */
@@ -168,9 +169,10 @@ static int findindex (lua_State *L, Table *t, StkId key) { · 4 unmodified lines
168 /* hash elements are numbered after array ones */169 /* hash elements are numbered after array ones */
169 return i + t->sizearray;170 return i + t->sizearray;
170 }171 }
171 else n = gnext(n);172 nx = gnext(n);
172 if (n == NULL)173 if (nx == 0)
173 luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */174 luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */
175 else n += nx;
174 }176 }
175 }177 }
176}178}
@@ -301,7 +303,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { · 124 unmodified lines
301 t->node = luaM_newvector(L, size, Node);303 t->node = luaM_newvector(L, size, Node);
302 for (i=0; i<size; i++) {304 for (i=0; i<size; i++) {
303 Node *n = gnode(t, i);305 Node *n = gnode(t, i);
304 gnext(n) = NULL;306 gnext(n) = 0;
305 setnilvalue(gkey(n));307 setnilvalue(gkey(n));
306 setnilvalue(gval(n));308 setnilvalue(gval(n));
307 }309 }
@@ -376,7 +378,7 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) { · 68 unmodified lines
376 378
377 379
378Table *luaH_new (lua_State *L) {380Table *luaH_new (lua_State *L) {
379 Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table), NULL, 0)->h;381 Table *t = &luaC_newobj(L, LUA_TTABLE, sizeof(Table))->h;
380 t->metatable = NULL;382 t->metatable = NULL;
381 t->flags = cast_byte(~0);383 t->flags = cast_byte(~0);
382 t->array = NULL;384 t->array = NULL;
@@ -419,7 +421,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { · 36 unmodified lines
419 else if (ttisfloat(key)) {421 else if (ttisfloat(key)) {
420 lua_Number n = fltvalue(key);422 lua_Number n = fltvalue(key);
421 lua_Integer k;423 lua_Integer k;
422 if (luai_numisnan(L, n))424 if (luai_numisnan(n))
423 luaG_runerror(L, "table index is NaN");425 luaG_runerror(L, "table index is NaN");
424 if (numisinteger(n, &k)) { /* index is int? */426 if (numisinteger(n, &k)) { /* index is int? */
425 setivalue(&aux, k); 427 setivalue(&aux, k);
@@ -429,31 +431,37 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { · 3 unmodified lines
429 mp = mainposition(t, key);431 mp = mainposition(t, key);
430 if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */432 if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */
431 Node *othern;433 Node *othern;
432 Node *n = getfreepos(t); /* get a free place */434 Node *f = getfreepos(t); /* get a free place */
433 if (n == NULL) { /* cannot find a free place? */435 if (f == NULL) { /* cannot find a free place? */
434 rehash(L, t, key); /* grow table */436 rehash(L, t, key); /* grow table */
435 /* whatever called 'newkey' take care of TM cache and GC barrier */437 /* whatever called 'newkey' take care of TM cache and GC barrier */
436 return luaH_set(L, t, key); /* insert key into grown table */438 return luaH_set(L, t, key); /* insert key into grown table */
437 }439 }
438 lua_assert(!isdummy(n));440 lua_assert(!isdummy(f));
439 othern = mainposition(t, gkey(mp));441 othern = mainposition(t, gkey(mp));
440 if (othern != mp) { /* is colliding node out of its main position? */442 if (othern != mp) { /* is colliding node out of its main position? */
441 /* yes; move colliding node into free position */443 /* yes; move colliding node into free position */
442 while (gnext(othern) != mp) othern = gnext(othern); /* find previous */444 while (othern + gnext(othern) != mp) /* find previous */
443 gnext(othern) = n; /* redo the chain with `n' in place of `mp' */445 othern += gnext(othern);
444 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */446 gnext(othern) = f - othern; /* re-chain with 'f' in place of 'mp' */
445 gnext(mp) = NULL; /* now `mp' is free */447 *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */
448 if (gnext(mp) != 0) {
449 gnext(f) += mp - f; /* correct 'next' */
450 gnext(mp) = 0; /* now 'mp' is free */
451 }
446 setnilvalue(gval(mp));452 setnilvalue(gval(mp));
447 }453 }
448 else { /* colliding node is in its own main position */454 else { /* colliding node is in its own main position */
449 /* new node will go into free position */455 /* new node will go into free position */
450 gnext(n) = gnext(mp); /* chain new position */456 if (gnext(mp) != 0)
451 gnext(mp) = n;457 gnext(f) = (mp + gnext(mp)) - f; /* chain new position */
452 mp = n;458 else lua_assert(gnext(f) == 0);
459 gnext(mp) = f - mp;
460 mp = f;
453 }461 }
454 }462 }
455 setobj2t(L, gkey(mp), key);463 setobj2t(L, gkey(mp), key);
456 luaC_barrierback(L, obj2gco(t), key);464 luaC_barrierback(L, t, key);
457 lua_assert(ttisnil(gval(mp)));465 lua_assert(ttisnil(gval(mp)));
458 return gval(mp);466 return gval(mp);
459}467}
@@ -468,11 +476,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { · 8 unmodified lines
468 return &t->array[key - 1];476 return &t->array[key - 1];
469 else {477 else {
470 Node *n = hashint(t, key);478 Node *n = hashint(t, key);
471 do { /* check whether `key' is somewhere in the chain */479 for (;;) { /* check whether `key' is somewhere in the chain */
472 if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)480 if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key)
473 return gval(n); /* that's it */481 return gval(n); /* that's it */
474 else n = gnext(n);482 else {
475 } while (n);483 int nx = gnext(n);
484 if (nx == 0) break;
485 n += nx;
486 }
487 };
476 return luaO_nilobject;488 return luaO_nilobject;
477 }489 }
478}490}
@@ -484,11 +496,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { · 5 unmodified lines
484const TValue *luaH_getstr (Table *t, TString *key) {496const TValue *luaH_getstr (Table *t, TString *key) {
485 Node *n = hashstr(t, key);497 Node *n = hashstr(t, key);
486 lua_assert(key->tsv.tt == LUA_TSHRSTR);498 lua_assert(key->tsv.tt == LUA_TSHRSTR);
487 do { /* check whether `key' is somewhere in the chain */499 for (;;) { /* check whether `key' is somewhere in the chain */
488 if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))500 if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key))
489 return gval(n); /* that's it */501 return gval(n); /* that's it */
490 else n = gnext(n);502 else {
491 } while (n);503 int nx = gnext(n);
504 if (nx == 0) break;
505 n += nx;
506 }
507 };
492 return luaO_nilobject;508 return luaO_nilobject;
493}509}
494 510
@@ -509,11 +525,15 @@ const TValue *luaH_get (Table *t, const TValue *key) { · 14 unmodified lines
509 }525 }
510 default: {526 default: {
511 Node *n = mainposition(t, key);527 Node *n = mainposition(t, key);
512 do { /* check whether `key' is somewhere in the chain */528 for (;;) { /* check whether `key' is somewhere in the chain */
513 if (luaV_rawequalobj(gkey(n), key))529 if (luaV_rawequalobj(gkey(n), key))
514 return gval(n); /* that's it */530 return gval(n); /* that's it */
515 else n = gnext(n);531 else {
516 } while (n);532 int nx = gnext(n);
533 if (nx == 0) break;
534 n += nx;
535 }
536 };
517 return luaO_nilobject;537 return luaO_nilobject;
518 }538 }
519 }539 }
src/ltable.h+6−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltable.h,v 2.17 2013/04/26 15:39:25 roberto Exp $2** $Id: ltable.h,v 2.18 2013/08/30 16:01:37 roberto Exp $
3** Lua tables (hash)3** Lua tables (hash)
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -18,6 +18,11 @@ · 12 unmodified lines
18#define invalidateTMcache(t) ((t)->flags = 0)18#define invalidateTMcache(t) ((t)->flags = 0)
19 19
20 20
21/* returns the key, given the value of a table entry */
22#define keyfromval(v) \
23 (gkey(cast(Node *, cast(char *, (v)) - offsetof(Node, i_val))))
24
25
21LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);26LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
22LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,27LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
23 TValue *value);28 TValue *value);
src/ltablib.c+2−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltablib.c,v 1.65 2013/03/07 18:17:24 roberto Exp $2** $Id: ltablib.c,v 1.66 2014/03/21 13:52:33 roberto Exp $
3** Library for Table Manipulation3** Library for Table Manipulation
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -140,7 +140,7 @@ static int unpack (lua_State *L) { · 134 unmodified lines
140 e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));140 e = luaL_opt(L, luaL_checkint, 3, luaL_len(L, 1));
141 if (i > e) return 0; /* empty range */141 if (i > e) return 0; /* empty range */
142 n = e - i + 1; /* number of elements */142 n = e - i + 1; /* number of elements */
143 if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arith. overflow */143 if (n <= 0 || !lua_checkstack(L, n)) /* n <= 0 means arithmetic overflow */
144 return luaL_error(L, "too many results to unpack");144 return luaL_error(L, "too many results to unpack");
145 lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */145 lua_rawgeti(L, 1, i); /* push arg[i] (avoiding overflow problems) */
146 while (i++ < e) /* push arg[i + 1...e] */146 while (i++ < e) /* push arg[i + 1...e] */
src/ltm.c+18−11
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltm.c,v 2.20 2013/05/06 17:19:11 roberto Exp $2** $Id: ltm.c,v 2.25 2013/12/30 20:47:58 roberto Exp $
3** Tag methods3** Tag methods
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -28,7 +28,7 @@ LUAI_DDEF const char *const luaT_typenames_[LUA_TOTALTAGS] = { · 22 unmodified lines
28 "no value",28 "no value",
29 "nil", "boolean", udatatypename, "number",29 "nil", "boolean", udatatypename, "number",
30 "string", "table", "function", udatatypename, "thread",30 "string", "table", "function", udatatypename, "thread",
31 "proto", "upval" /* these last two cases are used for tests only */31 "proto" /* this last case is used for tests only */
32};32};
33 33
34 34
@@ -36,14 +36,16 @@ void luaT_init (lua_State *L) { · 1 unmodified line
36 static const char *const luaT_eventname[] = { /* ORDER TM */36 static const char *const luaT_eventname[] = { /* ORDER TM */
37 "__index", "__newindex",37 "__index", "__newindex",
38 "__gc", "__mode", "__len", "__eq",38 "__gc", "__mode", "__len", "__eq",
39 "__add", "__sub", "__mul", "__div", "__idiv", "__mod",39 "__add", "__sub", "__mul", "__mod", "__pow",
40 "__pow", "__unm", "__lt", "__le",40 "__div", "__idiv",
41 "__band", "__bor", "__bxor", "__shl", "__shr",
42 "__unm", "__bnot", "__lt", "__le",
41 "__concat", "__call"43 "__concat", "__call"
42 };44 };
43 int i;45 int i;
44 for (i=0; i<TM_N; i++) {46 for (i=0; i<TM_N; i++) {
45 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);47 G(L)->tmname[i] = luaS_new(L, luaT_eventname[i]);
46 luaS_fix(G(L)->tmname[i]); /* never collect these names */48 luaC_fix(L, obj2gco(G(L)->tmname[i])); /* never collect these names */
47 }49 }
48}50}
49 51
@@ -110,12 +112,17 @@ int luaT_callbinTM (lua_State *L, const TValue *p1, const TValue *p2, · 60 unmodified lines
110void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,112void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
111 StkId res, TMS event) {113 StkId res, TMS event) {
112 if (!luaT_callbinTM(L, p1, p2, res, event)) {114 if (!luaT_callbinTM(L, p1, p2, res, event)) {
113 if (event == TM_CONCAT)115 switch (event) {
114 luaG_concaterror(L, p1, p2);116 case TM_CONCAT:
115 else if (event == TM_IDIV && ttisnumber(p1) && ttisnumber(p2))117 luaG_concaterror(L, p1, p2);
116 luaG_tointerror(L, p1, p2);118 case TM_IDIV: case TM_BAND: case TM_BOR: case TM_BXOR:
117 else119 case TM_SHL: case TM_SHR: case TM_BNOT:
118 luaG_aritherror(L, p1, p2);120 if (ttisnumber(p1) && ttisnumber(p2))
121 luaG_tointerror(L, p1, p2);
122 /* else go through */
123 default:
124 luaG_aritherror(L, p1, p2);
125 }
119 }126 }
120}127}
121 128
src/ltm.h+10−4
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: ltm.h,v 2.16 2013/04/29 16:56:50 roberto Exp $2** $Id: ltm.h,v 2.19 2013/12/30 20:47:58 roberto Exp $
3** Tag methods3** Tag methods
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -13,7 +13,7 @@ · 7 unmodified lines
13 13
14/*14/*
15* WARNING: if you change the order of this enumeration,15* WARNING: if you change the order of this enumeration,
16* grep "ORDER TM"16* grep "ORDER TM" and "ORDER OP"
17*/17*/
18typedef enum {18typedef enum {
19 TM_INDEX,19 TM_INDEX,
@@ -25,11 +25,17 @@ typedef enum { · 5 unmodified lines
25 TM_ADD,25 TM_ADD,
26 TM_SUB,26 TM_SUB,
27 TM_MUL,27 TM_MUL,
28 TM_DIV,
29 TM_IDIV,
30 TM_MOD,28 TM_MOD,
31 TM_POW,29 TM_POW,
30 TM_DIV,
31 TM_IDIV,
32 TM_BAND,
33 TM_BOR,
34 TM_BXOR,
35 TM_SHL,
36 TM_SHR,
32 TM_UNM,37 TM_UNM,
38 TM_BNOT,
33 TM_LT,39 TM_LT,
34 TM_LE,40 TM_LE,
35 TM_CONCAT,41 TM_CONCAT,
src/lua.c+69−31
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lua.c,v 1.206 2012/09/29 20:07:06 roberto Exp $2** $Id: lua.c,v 1.210 2014/02/26 15:27:56 roberto Exp $
3** Lua stand-alone interpreter3** Lua stand-alone interpreter
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -31,28 +31,38 @@ · 25 unmodified lines
31#define LUA_MAXINPUT 51231#define LUA_MAXINPUT 512
32#endif32#endif
33 33
34#if !defined(LUA_INIT)34#if !defined(LUA_INIT_VAR)
35#define LUA_INIT "LUA_INIT"35#define LUA_INIT_VAR "LUA_INIT"
36#endif36#endif
37 37
38#define LUA_INITVERSION \38#define LUA_INITVARVERSION \
39 LUA_INIT "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR39 LUA_INIT_VAR "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
40 40
41 41
42/*42/*
43** lua_stdin_is_tty detects whether the standard input is a 'tty' (that43** lua_stdin_is_tty detects whether the standard input is a 'tty' (that
44** is, whether we're running lua interactively).44** is, whether we're running lua interactively).
45*/45*/
46#if defined(LUA_USE_ISATTY)46#if !defined(lua_stdin_is_tty) /* { */
47
48#if defined(LUA_USE_POSIX) /* { */
49
47#include <unistd.h>50#include <unistd.h>
48#define lua_stdin_is_tty() isatty(0)51#define lua_stdin_is_tty() isatty(0)
49#elif defined(LUA_WIN)52
53#elif defined(LUA_WIN) /* }{ */
54
50#include <io.h>55#include <io.h>
51#include <stdio.h>
52#define lua_stdin_is_tty() _isatty(_fileno(stdin))56#define lua_stdin_is_tty() _isatty(_fileno(stdin))
53#else57
58#else /* }{ */
59
60/* ANSI definition */
54#define lua_stdin_is_tty() 1 /* assume stdin is a tty */61#define lua_stdin_is_tty() 1 /* assume stdin is a tty */
55#endif62
63#endif /* } */
64
65#endif /* } */
56 66
57 67
58/*68/*
@@ -61,9 +71,10 @@ · 2 unmodified lines
61** lua_saveline defines how to "save" a read line in a "history".71** lua_saveline defines how to "save" a read line in a "history".
62** lua_freeline defines how to free a line read by lua_readline.72** lua_freeline defines how to free a line read by lua_readline.
63*/73*/
64#if defined(LUA_USE_READLINE)74#if !defined(lua_readline) /* { */
75
76#if defined(LUA_USE_READLINE) /* { */
65 77
66#include <stdio.h>
67#include <readline/readline.h>78#include <readline/readline.h>
68#include <readline/history.h>79#include <readline/history.h>
69#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)80#define lua_readline(L,b,p) ((void)L, ((b)=readline(p)) != NULL)
@@ -72,7 +83,7 @@ · 2 unmodified lines
72 add_history(lua_tostring(L, idx)); /* add it to history */83 add_history(lua_tostring(L, idx)); /* add it to history */
73#define lua_freeline(L,b) ((void)L, free(b))84#define lua_freeline(L,b) ((void)L, free(b))
74 85
75#elif !defined(lua_readline)86#else /* }{ */
76 87
77#define lua_readline(L,b,p) \88#define lua_readline(L,b,p) \
78 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \89 ((void)L, fputs(p, stdout), fflush(stdout), /* show prompt */ \
@@ -80,7 +91,9 @@ · 1 unmodified line
80#define lua_saveline(L,idx) { (void)L; (void)idx; }91#define lua_saveline(L,idx) { (void)L; (void)idx; }
81#define lua_freeline(L,b) { (void)L; (void)b; }92#define lua_freeline(L,b) { (void)L; (void)b; }
82 93
83#endif94#endif /* } */
95
96#endif /* } */
84 97
85 98
86 99
@@ -257,20 +270,21 @@ static int incomplete (lua_State *L, int status) { · 170 unmodified lines
257}270}
258 271
259 272
273/* prompt the user, read a line, and push it into the Lua stack */
260static int pushline (lua_State *L, int firstline) {274static int pushline (lua_State *L, int firstline) {
261 char buffer[LUA_MAXINPUT];275 char buffer[LUA_MAXINPUT];
262 char *b = buffer;276 char *b = buffer;
263 size_t l;277 size_t l;
264 const char *prmt = get_prompt(L, firstline);278 const char *prmt = get_prompt(L, firstline);
265 int readstatus = lua_readline(L, b, prmt);279 int readstatus = lua_readline(L, b, prmt);
266 lua_pop(L, 1); /* remove result from 'get_prompt' */
267 if (readstatus == 0)280 if (readstatus == 0)
268 return 0; /* no input */281 return 0; /* no input (prompt will be popped by caller) */
282 lua_pop(L, 1); /* remove prompt */
269 l = strlen(b);283 l = strlen(b);
270 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */284 if (l > 0 && b[l-1] == '\n') /* line ends with newline? */
271 b[l-1] = '\0'; /* remove it */285 b[l-1] = '\0'; /* remove it */
272 if (firstline && b[0] == '=') /* first line starts with `=' ? */286 if (firstline && b[0] == '=') /* for compatibility with 5.2, ... */
273 lua_pushfstring(L, "return %s", b+1); /* change it to `return' */287 lua_pushfstring(L, "return %s", b + 1); /* change '=' to 'return' */
274 else288 else
275 lua_pushstring(L, b);289 lua_pushstring(L, b);
276 lua_freeline(L, b);290 lua_freeline(L, b);
@@ -278,24 +292,48 @@ static int pushline (lua_State *L, int firstline) { · 1 unmodified line
278}292}
279 293
280 294
281static int loadline (lua_State *L) {295/* try to compile line on the stack as 'return <line>'; on return, stack
296 has either compiled chunk or original line (if compilation failed) */
297static int addreturn (lua_State *L) {
282 int status;298 int status;
283 lua_settop(L, 0);299 size_t len; const char *line;
284 if (!pushline(L, 1))300 lua_pushliteral(L, "return ");
285 return -1; /* no input */301 lua_pushvalue(L, -2); /* duplicate line */
302 lua_concat(L, 2); /* new line is "return ..." */
303 line = lua_tolstring(L, -1, &len);
304 if ((status = luaL_loadbuffer(L, line, len, "=stdin")) == LUA_OK)
305 lua_remove(L, -3); /* remove original line */
306 else
307 lua_pop(L, 2); /* remove result from 'luaL_loadbuffer' and new line */
308 return status;
309}
310
311
312/* read multiple lines until a complete line */
313static int multiline (lua_State *L) {
286 for (;;) { /* repeat until gets a complete line */314 for (;;) { /* repeat until gets a complete line */
287 size_t l;315 size_t len;
288 const char *line = lua_tolstring(L, 1, &l);316 const char *line = lua_tolstring(L, 1, &len); /* get what it has */
289 status = luaL_loadbuffer(L, line, l, "=stdin");317 int status = luaL_loadbuffer(L, line, len, "=stdin"); /* try it */
290 if (!incomplete(L, status)) break; /* cannot try to add lines? */318 if (!incomplete(L, status) || !pushline(L, 0))
291 if (!pushline(L, 0)) /* no more input? */319 return status; /* cannot/should not try to add continuation line */
292 return -1;320 lua_pushliteral(L, "\n"); /* add newline... */
293 lua_pushliteral(L, "\n"); /* add a new line... */
294 lua_insert(L, -2); /* ...between the two lines */321 lua_insert(L, -2); /* ...between the two lines */
295 lua_concat(L, 3); /* join them */322 lua_concat(L, 3); /* join them */
296 }323 }
324}
325
326
327static int loadline (lua_State *L) {
328 int status;
329 lua_settop(L, 0);
330 if (!pushline(L, 1))
331 return -1; /* no input */
332 if ((status = addreturn(L)) != LUA_OK) /* 'return ...' did not work? */
333 status = multiline(L); /* try as command, maybe with continuation lines */
297 lua_saveline(L, 1);334 lua_saveline(L, 1);
298 lua_remove(L, 1); /* remove line */335 lua_remove(L, 1); /* remove line */
336 lua_assert(lua_gettop(L) == 1);
299 return status;337 return status;
300}338}
301 339
@@ -421,10 +459,10 @@ static int runargs (lua_State *L, char **argv, int n) { · 119 unmodified lines
421 459
422 460
423static int handle_luainit (lua_State *L) {461static int handle_luainit (lua_State *L) {
424 const char *name = "=" LUA_INITVERSION;462 const char *name = "=" LUA_INITVARVERSION;
425 const char *init = getenv(name + 1);463 const char *init = getenv(name + 1);
426 if (init == NULL) {464 if (init == NULL) {
427 name = "=" LUA_INIT;465 name = "=" LUA_INIT_VAR;
428 init = getenv(name + 1); /* try alternative name */466 init = getenv(name + 1); /* try alternative name */
429 }467 }
430 if (init == NULL) return LUA_OK;468 if (init == NULL) return LUA_OK;
src/lua.h+25−21
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lua.h,v 1.292 2013/07/05 14:29:51 roberto Exp $2** $Id: lua.h,v 1.302 2014/03/20 19:42:35 roberto Exp $
3** Lua - A Scripting Language3** Lua - A Scripting Language
4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)4** Lua.org, PUC-Rio, Brazil (http://www.lua.org)
5** See Copyright Notice at the end of this file5** See Copyright Notice at the end of this file
@@ -19,11 +19,11 @@ · 13 unmodified lines
19#define LUA_VERSION_MAJOR "5"19#define LUA_VERSION_MAJOR "5"
20#define LUA_VERSION_MINOR "3"20#define LUA_VERSION_MINOR "3"
21#define LUA_VERSION_NUM 50321#define LUA_VERSION_NUM 503
22#define LUA_VERSION_RELEASE "0 (work1)"22#define LUA_VERSION_RELEASE "0 (work2)"
23 23
24#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR24#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
25#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE25#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
26#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2013 Lua.org, PUC-Rio"26#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2014 Lua.org, PUC-Rio"
27#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"27#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
28 28
29 29
@@ -182,14 +182,20 @@ LUA_API const void *(lua_topointer) (lua_State *L, int idx); · 152 unmodified lines
182** Comparison and arithmetic functions182** Comparison and arithmetic functions
183*/183*/
184 184
185#define LUA_OPADD 0 /* ORDER TM */185#define LUA_OPADD 0 /* ORDER TM, ORDER OP */
186#define LUA_OPSUB 1186#define LUA_OPSUB 1
187#define LUA_OPMUL 2187#define LUA_OPMUL 2
188#define LUA_OPDIV 3188#define LUA_OPMOD 3
189#define LUA_OPIDIV 4189#define LUA_OPPOW 4
190#define LUA_OPMOD 5190#define LUA_OPDIV 5
191#define LUA_OPPOW 6191#define LUA_OPIDIV 6
192#define LUA_OPUNM 7192#define LUA_OPBAND 7
193#define LUA_OPBOR 8
194#define LUA_OPBXOR 9
195#define LUA_OPSHL 10
196#define LUA_OPSHR 11
197#define LUA_OPUNM 12
198#define LUA_OPBNOT 13
193 199
194LUA_API void (lua_arith) (lua_State *L, int op);200LUA_API void (lua_arith) (lua_State *L, int op);
195 201
@@ -222,12 +228,13 @@ LUA_API int (lua_pushthread) (lua_State *L); · 26 unmodified lines
222/*228/*
223** get functions (Lua -> stack)229** get functions (Lua -> stack)
224*/230*/
225LUA_API void (lua_getglobal) (lua_State *L, const char *var);231LUA_API int (lua_getglobal) (lua_State *L, const char *var);
226LUA_API void (lua_gettable) (lua_State *L, int idx);232LUA_API int (lua_gettable) (lua_State *L, int idx);
227LUA_API void (lua_getfield) (lua_State *L, int idx, const char *k);233LUA_API int (lua_getfield) (lua_State *L, int idx, const char *k);
228LUA_API void (lua_rawget) (lua_State *L, int idx);234LUA_API int (lua_rawget) (lua_State *L, int idx);
229LUA_API void (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);235LUA_API int (lua_rawgeti) (lua_State *L, int idx, lua_Integer n);
230LUA_API void (lua_rawgetp) (lua_State *L, int idx, const void *p);236LUA_API int (lua_rawgetp) (lua_State *L, int idx, const void *p);
237
231LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);238LUA_API void (lua_createtable) (lua_State *L, int narr, int nrec);
232LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);239LUA_API void *(lua_newuserdata) (lua_State *L, size_t sz);
233LUA_API int (lua_getmetatable) (lua_State *L, int objindex);240LUA_API int (lua_getmetatable) (lua_State *L, int objindex);
@@ -264,7 +271,7 @@ LUA_API int (lua_load) (lua_State *L, lua_Reader reader, void *dt, · 30 unmodified lines
264 const char *chunkname,271 const char *chunkname,
265 const char *mode);272 const char *mode);
266 273
267LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data);274LUA_API int (lua_dump) (lua_State *L, lua_Writer writer, void *data, int strip);
268 275
269 276
270/*277/*
@@ -288,10 +295,7 @@ LUA_API int (lua_status) (lua_State *L); · 17 unmodified lines
288#define LUA_GCSTEP 5295#define LUA_GCSTEP 5
289#define LUA_GCSETPAUSE 6296#define LUA_GCSETPAUSE 6
290#define LUA_GCSETSTEPMUL 7297#define LUA_GCSETSTEPMUL 7
291#define LUA_GCSETMAJORINC 8
292#define LUA_GCISRUNNING 9298#define LUA_GCISRUNNING 9
293#define LUA_GCGEN 10
294#define LUA_GCINC 11
295 299
296LUA_API int (lua_gc) (lua_State *L, int what, int data);300LUA_API int (lua_gc) (lua_State *L, int what, int data);
297 301
@@ -394,7 +398,7 @@ LUA_API void *(lua_upvalueid) (lua_State *L, int fidx, int n); · 96 unmodified lines
394LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,398LUA_API void (lua_upvaluejoin) (lua_State *L, int fidx1, int n1,
395 int fidx2, int n2);399 int fidx2, int n2);
396 400
397LUA_API int (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);401LUA_API void (lua_sethook) (lua_State *L, lua_Hook func, int mask, int count);
398LUA_API lua_Hook (lua_gethook) (lua_State *L);402LUA_API lua_Hook (lua_gethook) (lua_State *L);
399LUA_API int (lua_gethookmask) (lua_State *L);403LUA_API int (lua_gethookmask) (lua_State *L);
400LUA_API int (lua_gethookcount) (lua_State *L);404LUA_API int (lua_gethookcount) (lua_State *L);
@@ -422,7 +426,7 @@ struct lua_Debug { · 21 unmodified lines
422 426
423 427
424/******************************************************************************428/******************************************************************************
425* Copyright (C) 1994-2013 Lua.org, PUC-Rio.429* Copyright (C) 1994-2014 Lua.org, PUC-Rio.
426*430*
427* Permission is hereby granted, free of charge, to any person obtaining431* Permission is hereby granted, free of charge, to any person obtaining
428* a copy of this software and associated documentation files (the432* a copy of this software and associated documentation files (the
src/luac.c+1−1
@@ -202,7 +202,7 @@ int main(int argc, char* argv[]) · 201 unmodified lines
202 return EXIT_SUCCESS;202 return EXIT_SUCCESS;
203}203}
204 204
205#define nvalue(x) 0205#define nvalue(x) ((lua_Number)0)
206#define ttypenv(x) ttnov(x)206#define ttypenv(x) ttnov(x)
207/*207/*
208** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $208** $Id: print.c,v 1.69 2013/07/04 01:03:46 lhf Exp $
src/luaconf.h+76−44
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: luaconf.h,v 1.185 2013/06/25 19:04:40 roberto Exp $2** $Id: luaconf.h,v 1.193 2014/03/21 14:27:16 roberto Exp $
3** Configuration file for Lua3** Configuration file for Lua
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -19,6 +19,24 @@ · 13 unmodified lines
19*/19*/
20 20
21 21
22/*
23** ===================================================================
24@@ LUA_INT_INT / LUA_INT_LONG / LUA_INT_LONGLONG defines size for
25@* Lua integers;
26@@ LUA_REAL_FLOAT / LUA_REAL_DOUBLE / LUA_REAL_LONGDOUBLE defines size for
27@* Lua floats.
28**
29** These definitions set the numeric types for Lua. Lua should work
30** fine with 32-bit or 64-bit integers mixed with 32-bit or 64-bit
31** floats. The usual configurations are 64-bit integers and floats (the
32** default) and 32-bit integers and floats (Small Lua, for restricted
33** hardware).
34** =====================================================================
35*/
36#define LUA_INT_LONGLONG
37#define LUA_REAL_DOUBLE
38
39
22/*40/*
23@@ LUA_ANSI controls the use of non-ansi features.41@@ LUA_ANSI controls the use of non-ansi features.
24** CHANGE it (define it) if you want Lua to avoid the use of any42** CHANGE it (define it) if you want Lua to avoid the use of any
@@ -41,24 +59,28 @@ · 16 unmodified lines
41 59
42 60
43#if defined(LUA_USE_LINUX)61#if defined(LUA_USE_LINUX)
62#define LUA_USE_C99
44#define LUA_USE_POSIX63#define LUA_USE_POSIX
45#define LUA_USE_DLOPEN /* needs an extra library: -ldl */64#define LUA_USE_DLOPEN /* needs an extra library: -ldl */
46#define LUA_USE_READLINE /* needs some extra libraries */65#define LUA_USE_READLINE /* needs some extra libraries */
47#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */
48#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
49#define LUA_USE_LONGLONG /* assume support for long long */
50#endif66#endif
51 67
52#if defined(LUA_USE_MACOSX)68#if defined(LUA_USE_MACOSX)
69#define LUA_USE_C99
53#define LUA_USE_POSIX70#define LUA_USE_POSIX
54#define LUA_USE_DLOPEN /* does not need -ldl */71#define LUA_USE_DLOPEN /* does not need -ldl */
55#define LUA_USE_READLINE /* needs an extra library: -lreadline */72#define LUA_USE_READLINE /* needs an extra library: -lreadline */
56#define LUA_USE_STRTODHEX /* assume 'strtod' handles hex formats */
57#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
58#define LUA_USE_LONGLONG /* assume support for long long */
59#endif73#endif
60 74
61 75
76/*
77@@ LUA_USE_C99 includes all functionality from C 99.
78** CHANGE it (define it) if your system is compatible.
79*/
80#if defined(LUA_USE_C99)
81#define LUA_USE_AFORMAT /* assume 'printf' handles 'aA' specifiers */
82#endif
83
62 84
63/*85/*
64@@ LUA_USE_POSIX includes all functionality listed as X/Open System86@@ LUA_USE_POSIX includes all functionality listed as X/Open System
@@ -66,11 +88,6 @@ · 1 unmodified line
66** CHANGE it (define it) if your system is XSI compatible.88** CHANGE it (define it) if your system is XSI compatible.
67*/89*/
68#if defined(LUA_USE_POSIX)90#if defined(LUA_USE_POSIX)
69#define LUA_USE_MKSTEMP
70#define LUA_USE_ISATTY
71#define LUA_USE_POPEN
72#define LUA_USE_ULONGJMP
73#define LUA_USE_GMTIME_R
74#endif91#endif
75 92
76 93
@@ -93,7 +110,8 @@ · 16 unmodified lines
93#define LUA_CDIR "!\\"110#define LUA_CDIR "!\\"
94#define LUA_PATH_DEFAULT \111#define LUA_PATH_DEFAULT \
95 LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \112 LUA_LDIR"?.lua;" LUA_LDIR"?\\init.lua;" \
96 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" ".\\?.lua"113 LUA_CDIR"?.lua;" LUA_CDIR"?\\init.lua;" \
114 ".\\?.lua;" ".\\?\\init.lua"
97#define LUA_CPATH_DEFAULT \115#define LUA_CPATH_DEFAULT \
98 LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"116 LUA_CDIR"?.dll;" LUA_CDIR"loadall.dll;" ".\\?.dll"
99 117
@@ -105,7 +123,8 @@ · 5 unmodified lines
105#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR123#define LUA_CDIR LUA_ROOT "lib/lua/" LUA_VDIR
106#define LUA_PATH_DEFAULT \124#define LUA_PATH_DEFAULT \
107 LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \125 LUA_LDIR"?.lua;" LUA_LDIR"?/init.lua;" \
108 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" "./?.lua"126 LUA_CDIR"?.lua;" LUA_CDIR"?/init.lua;" \
127 "./?.lua;" "./?/init.lua"
109#define LUA_CPATH_DEFAULT \128#define LUA_CPATH_DEFAULT \
110 LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"129 LUA_CDIR"?.so;" LUA_CDIR"loadall.so;" "./?.so"
111#endif /* } */130#endif /* } */
@@ -246,6 +265,11 @@ · 134 unmodified lines
246*/265*/
247#if defined(LUA_COMPAT_ALL) /* { */266#if defined(LUA_COMPAT_ALL) /* { */
248 267
268/*
269@@ LUA_COMPAT_BITLIB controls the presence of library 'bit32'.
270*/
271#define LUA_COMPAT_BITLIB
272
249/*273/*
250@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.274@@ LUA_COMPAT_UNPACK controls the presence of global 'unpack'.
251** You can replace it with 'table.unpack'.275** You can replace it with 'table.unpack'.
@@ -350,7 +374,7 @@ · 98 unmodified lines
350/*374/*
351@@ LUAI_MAXSTACK limits the size of the Lua stack.375@@ LUAI_MAXSTACK limits the size of the Lua stack.
352** CHANGE it if you need a different limit. This limit is arbitrary;376** CHANGE it if you need a different limit. This limit is arbitrary;
353** its only purpose is to stop Lua to consume unlimited stack377** its only purpose is to stop Lua from consuming unlimited stack
354** space (and to reserve some numbers for pseudo-indices).378** space (and to reserve some numbers for pseudo-indices).
355*/379*/
356#if LUAI_BITSINT >= 32380#if LUAI_BITSINT >= 32
@@ -372,26 +396,14 @@ · 15 unmodified lines
372#define LUAL_BUFFERSIZE BUFSIZ396#define LUAL_BUFFERSIZE BUFSIZ
373 397
374 398
375
376
377/*399/*
378** {==================================================================400** {==================================================================
379** The following definitions set the numeric types for Lua.401** Configuration for Numbers.
380** Lua should work fine with 32-bit or 64-bit integers mixed with402** Change these definitions if no predefined LUA_REAL_* / LUA_INT_*
381** 32-bit or 64-bit floats. The usual configurations are 64-bit403** satisfy your needs.
382** integers and floats (the default) and 32-bit integers and floats.
383** ===================================================================404** ===================================================================
384*/405*/
385 406
386/*
387@@ LUA_INTSIZE defines size for Lua integer: 1=int, 2=long, 3=long long
388@@ LUA_FLOATSIZE defines size for Lua float: 1=float, 2=double, 3=long double
389** Default is long long + double
390*/
391#define LUA_INTSIZE 3
392#define LUA_FLOATSIZE 2
393
394
395/*407/*
396@@ LUA_NUMBER is the floating-point type used by Lua.408@@ LUA_NUMBER is the floating-point type used by Lua.
397**409**
@@ -401,14 +413,14 @@ · 3 unmodified lines
401@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.413@@ LUA_NUMBER_FRMLEN is the length modifier for writing floats.
402@@ LUA_NUMBER_SCAN is the format for reading floats.414@@ LUA_NUMBER_SCAN is the format for reading floats.
403@@ LUA_NUMBER_FMT is the format for writing floats.415@@ LUA_NUMBER_FMT is the format for writing floats.
404@@ lua_number2str converts a floats to a string.416@@ lua_number2str converts a float to a string.
405**417**
406@@ l_mathop allows the addition of an 'l' or 'f' to all math operations418@@ l_mathop allows the addition of an 'l' or 'f' to all math operations
407**419**
408@@ lua_str2number converts a decimal numeric string to a number.420@@ lua_str2number converts a decimal numeric string to a number.
409*/421*/
410 422
411#if LUA_FLOATSIZE == 1 /* { single float */423#if defined(LUA_REAL_FLOAT) /* { single float */
412 424
413#define LUA_NUMBER float425#define LUA_NUMBER float
414 426
@@ -423,7 +435,7 @@ · 8 unmodified lines
423#define lua_str2number(s,p) strtof((s), (p))435#define lua_str2number(s,p) strtof((s), (p))
424 436
425 437
426#elif LUA_FLOATSIZE == 3 /* }{ long double */438#elif defined(LUA_REAL_LONGDOUBLE) /* }{ long double */
427 439
428#define LUA_NUMBER long double440#define LUA_NUMBER long double
429 441
@@ -437,7 +449,7 @@ · 7 unmodified lines
437 449
438#define lua_str2number(s,p) strtold((s), (p))450#define lua_str2number(s,p) strtold((s), (p))
439 451
440#else /* }{ default: double */452#elif defined(LUA_REAL_DOUBLE) /* }{ double */
441 453
442#define LUA_NUMBER double454#define LUA_NUMBER double
443 455
@@ -451,7 +463,11 @@ · 7 unmodified lines
451 463
452#define lua_str2number(s,p) strtod((s), (p))464#define lua_str2number(s,p) strtod((s), (p))
453 465
454#endif /* } */466#else /* }{ */
467
468#error "numeric real type not defined"
469
470#endif /* } */
455 471
456 472
457#if defined(LUA_ANSI)473#if defined(LUA_ANSI)
@@ -481,8 +497,8 @@ · 23 unmodified lines
481/* the following operations need the math library */497/* the following operations need the math library */
482#if defined(lobject_c) || defined(lvm_c)498#if defined(lobject_c) || defined(lvm_c)
483#include <math.h>499#include <math.h>
484#define luai_nummod(L,a,b) ((a) - l_floor((a)/(b))*(b))500#define luai_nummod(L,a,b) ((void)L, (a) - l_floor((a)/(b))*(b))
485#define luai_numpow(L,a,b) (l_mathop(pow)(a,b))501#define luai_numpow(L,a,b) ((void)L, l_mathop(pow)(a,b))
486#endif502#endif
487 503
488/* these are quite standard operations */504/* these are quite standard operations */
@@ -493,12 +509,19 @@ · 4 unmodified lines
493#define luai_numdiv(L,a,b) ((a)/(b))509#define luai_numdiv(L,a,b) ((a)/(b))
494#define luai_numunm(L,a) (-(a))510#define luai_numunm(L,a) (-(a))
495#define luai_numeq(a,b) ((a)==(b))511#define luai_numeq(a,b) ((a)==(b))
496#define luai_numlt(L,a,b) ((a)<(b))512#define luai_numlt(a,b) ((a)<(b))
497#define luai_numle(L,a,b) ((a)<=(b))513#define luai_numle(a,b) ((a)<=(b))
498#define luai_numisnan(L,a) (!luai_numeq((a), (a)))514#define luai_numisnan(a) (!luai_numeq((a), (a)))
499#endif515#endif
500 516
501 517
518/*
519** The following macro checks whether an operation is not safe to be
520** performed by the constant folder. It should result in zero only if
521** the operation is safe.
522*/
523#define luai_numinvalidop(op,a,b) 0
524
502 525
503/*526/*
504@@ LUA_INTEGER is the integer type used by Lua.527@@ LUA_INTEGER is the integer type used by Lua.
@@ -511,22 +534,31 @@ · 6 unmodified lines
511@@ lua_integer2str converts an integer to a string.534@@ lua_integer2str converts an integer to a string.
512*/535*/
513 536
514#if LUA_INTSIZE == 1 /* { int */537#if defined(LUA_INT_INT) /* { int */
515 538
516#define LUA_INTEGER int539#define LUA_INTEGER int
517#define LUA_INTEGER_FRMLEN ""540#define LUA_INTEGER_FRMLEN ""
518 541
519#elif LUA_INTSIZE == 2 /* }{ long */542#elif defined(LUA_INT_LONG) /* }{ long */
520 543
521#define LUA_INTEGER long544#define LUA_INTEGER long
522#define LUA_INTEGER_FRMLEN "l"545#define LUA_INTEGER_FRMLEN "l"
523 546
524#else /* }{ default: long long */547#elif defined(LUA_INT_LONGLONG) /* }{ long long */
525 548
549#if defined(_WIN32)
550#define LUA_INTEGER __int64
551#define LUA_INTEGER_FRMLEN "I64"
552#else
526#define LUA_INTEGER long long553#define LUA_INTEGER long long
527#define LUA_INTEGER_FRMLEN "ll"554#define LUA_INTEGER_FRMLEN "ll"
555#endif
528 556
529#endif /* } */557#else /* }{ */
558
559#error "numeric integer type not defined"
560
561#endif /* } */
530 562
531 563
532#define LUA_INTEGER_SCAN "%" LUA_INTEGER_FRMLEN "d"564#define LUA_INTEGER_SCAN "%" LUA_INTEGER_FRMLEN "d"
src/lualib.h+4−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lualib.h,v 1.43 2011/12/08 12:11:37 roberto Exp $2** $Id: lualib.h,v 1.44 2014/02/06 17:32:33 roberto Exp $
3** Lua standard libraries3** Lua standard libraries
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -29,6 +29,9 @@ LUAMOD_API int (luaopen_os) (lua_State *L); · 23 unmodified lines
29#define LUA_STRLIBNAME "string"29#define LUA_STRLIBNAME "string"
30LUAMOD_API int (luaopen_string) (lua_State *L);30LUAMOD_API int (luaopen_string) (lua_State *L);
31 31
32#define LUA_UTF8LIBNAME "utf8"
33LUAMOD_API int (luaopen_utf8) (lua_State *L);
34
32#define LUA_BITLIBNAME "bit32"35#define LUA_BITLIBNAME "bit32"
33LUAMOD_API int (luaopen_bit32) (lua_State *L);36LUAMOD_API int (luaopen_bit32) (lua_State *L);
34 37
src/lundump.c+207−209
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lundump.c,v 2.23 2013/04/26 18:48:35 roberto Exp $2** $Id: lundump.c,v 2.34 2014/03/11 18:56:27 roberto Exp $
3** load precompiled Lua chunks3** load precompiled Lua chunks
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -20,249 +20,247 @@ · 14 unmodified lines
20#include "lundump.h"20#include "lundump.h"
21#include "lzio.h"21#include "lzio.h"
22 22
23
24#if !defined(luai_verifycode)
25#define luai_verifycode(L,b,f) /* empty */
26#endif
27
28
23typedef struct {29typedef struct {
24 lua_State* L;30 lua_State *L;
25 ZIO* Z;31 ZIO *Z;
26 Mbuffer* b;32 Mbuffer *b;
27 const char* name;33 const char *name;
28} LoadState;34} LoadState;
29 35
30static l_noret error(LoadState* S, const char* why)36
31{37static l_noret error(LoadState *S, const char *why) {
32 luaO_pushfstring(S->L,"%s: %s precompiled chunk",S->name,why);38 luaO_pushfstring(S->L, "%s: %s precompiled chunk", S->name, why);
33 luaD_throw(S->L,LUA_ERRSYNTAX);39 luaD_throw(S->L, LUA_ERRSYNTAX);
34}40}
35 41
36#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
37#define LoadByte(S) (lu_byte)LoadChar(S)
38#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
39#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
40 42
41#if !defined(luai_verifycode)43/*
42#define luai_verifycode(L,b,f) /* empty */44** All high-level loads go through LoadVector; you can change it to
43#endif45** adapt to the endianess of the input
46*/
47#define LoadVector(S,b,n) LoadBlock(S,b,(n)*sizeof((b)[0]))
44 48
45static void LoadBlock(LoadState* S, void* b, size_t size)49static void LoadBlock (LoadState *S, void *b, size_t size) {
46{50 if (luaZ_read(S->Z, b, size) != 0)
47 if (luaZ_read(S->Z,b,size)!=0) error(S,"truncated");51 error(S, "truncated");
48}52}
49 53
50static int LoadChar(LoadState* S)54
51{55#define LoadVar(S,x) LoadVector(S,&x,1)
52 char x;56
53 LoadVar(S,x);57
54 return x;58static lu_byte LoadByte (LoadState *S) {
59 lu_byte x;
60 LoadVar(S, x);
61 return x;
55}62}
56 63
57static int LoadInt(LoadState* S)64
58{65static int LoadInt (LoadState *S) {
59 int x;66 int x;
60 LoadVar(S,x);67 LoadVar(S, x);
61 if (x<0) error(S,"corrupted");68 return x;
62 return x;
63}69}
64 70
65static lua_Number LoadNumber(LoadState* S)71
66{72static lua_Number LoadNumber (LoadState *S) {
67 lua_Number x;73 lua_Number x;
68 LoadVar(S,x);74 LoadVar(S, x);
69 return x;75 return x;
70}76}
71 77
72static lua_Integer LoadInteger(LoadState* S)78
73{79static lua_Integer LoadInteger (LoadState *S) {
74 lua_Integer x;80 lua_Integer x;
75 LoadVar(S,x);81 LoadVar(S, x);
76 return x;82 return x;
77}83}
78 84
79static TString* LoadString(LoadState* S)85
80{86static TString *LoadString (LoadState *S) {
81 size_t size;87 size_t size = LoadByte(S);
82 LoadVar(S,size);88 if (size == 0xFF)
83 if (size==0)89 LoadVar(S, size);
84 return NULL;90 if (size == 0)
85 else91 return NULL;
86 {92 else {
87 char* s=luaZ_openspace(S->L,S->b,size);93 char *s = luaZ_openspace(S->L, S->b, --size);
88 LoadBlock(S,s,size*sizeof(char));94 LoadVector(S, s, size);
89 return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */95 return luaS_newlstr(S->L, s, size);
90 }96 }
91}97}
92 98
93static void LoadCode(LoadState* S, Proto* f)99
94{100static void LoadCode (LoadState *S, Proto *f) {
95 int n=LoadInt(S);101 int n = LoadInt(S);
96 f->code=luaM_newvector(S->L,n,Instruction);102 f->code = luaM_newvector(S->L, n, Instruction);
97 f->sizecode=n;103 f->sizecode = n;
98 LoadVector(S,f->code,n,sizeof(Instruction));104 LoadVector(S, f->code, n);
99}105}
100 106
101static void LoadFunction(LoadState* S, Proto* f);107
102 108static void LoadFunction(LoadState *S, Proto *f);
103static void LoadConstants(LoadState* S, Proto* f)109
104{110
105 int i,n;111static void LoadConstants (LoadState *S, Proto *f) {
106 n=LoadInt(S);112 int i, n;
107 f->k=luaM_newvector(S->L,n,TValue);113 n = LoadInt(S);
108 f->sizek=n;114 f->k = luaM_newvector(S->L, n, TValue);
109 for (i=0; i<n; i++) setnilvalue(&f->k[i]);115 f->sizek = n;
110 for (i=0; i<n; i++)116 for (i = 0; i < n; i++)
111 {117 setnilvalue(&f->k[i]);
112 TValue* o=&f->k[i];118 for (i = 0; i < n; i++) {
113 int t=LoadChar(S);119 TValue *o = &f->k[i];
114 switch (t)120 int t = LoadByte(S);
115 {121 switch (t) {
116 case LUA_TNIL:122 case LUA_TNIL:
117 setnilvalue(o);123 setnilvalue(o);
118 break;124 break;
119 case LUA_TBOOLEAN:125 case LUA_TBOOLEAN:
120 setbvalue(o,LoadChar(S));126 setbvalue(o, LoadByte(S));
121 break;127 break;
122 case LUA_TNUMFLT:128 case LUA_TNUMFLT:
123 setnvalue(o,LoadNumber(S));129 setnvalue(o, LoadNumber(S));
124 break;130 break;
125 case LUA_TNUMINT:131 case LUA_TNUMINT:
126 setivalue(o,LoadInteger(S));132 setivalue(o, LoadInteger(S));
127 break;133 break;
128 case LUA_TSHRSTR: case LUA_TLNGSTR:134 case LUA_TSHRSTR:
129 setsvalue2n(S->L,o,LoadString(S));135 case LUA_TLNGSTR:
130 break;136 setsvalue2n(S->L, o, LoadString(S));
131 default: lua_assert(0);137 break;
138 default:
139 lua_assert(0);
140 }
141 }
142 n = LoadInt(S);
143 f->p = luaM_newvector(S->L, n, Proto *);
144 f->sizep = n;
145 for (i = 0; i < n; i++)
146 f->p[i] = NULL;
147 for (i = 0; i < n; i++) {
148 f->p[i] = luaF_newproto(S->L);
149 LoadFunction(S, f->p[i]);
132 }150 }
133 }
134 n=LoadInt(S);
135 f->p=luaM_newvector(S->L,n,Proto*);
136 f->sizep=n;
137 for (i=0; i<n; i++) f->p[i]=NULL;
138 for (i=0; i<n; i++)
139 {
140 f->p[i]=luaF_newproto(S->L);
141 LoadFunction(S,f->p[i]);
142 }
143}151}
144 152
145static void LoadUpvalues(LoadState* S, Proto* f)153
146{154static void LoadUpvalues (LoadState *S, Proto *f) {
147 int i,n;155 int i, n;
148 n=LoadInt(S);156 n = LoadInt(S);
149 f->upvalues=luaM_newvector(S->L,n,Upvaldesc);157 f->upvalues = luaM_newvector(S->L, n, Upvaldesc);
150 f->sizeupvalues=n;158 f->sizeupvalues = n;
151 for (i=0; i<n; i++) f->upvalues[i].name=NULL;159 for (i = 0; i < n; i++)
152 for (i=0; i<n; i++)160 f->upvalues[i].name = NULL;
153 {161 for (i = 0; i < n; i++) {
154 f->upvalues[i].instack=LoadByte(S);162 f->upvalues[i].instack = LoadByte(S);
155 f->upvalues[i].idx=LoadByte(S);163 f->upvalues[i].idx = LoadByte(S);
156 }164 }
157}165}
158 166
159static void LoadDebug(LoadState* S, Proto* f)167
160{168static void LoadDebug (LoadState *S, Proto *f) {
161 int i,n;169 int i, n;
162 f->source=LoadString(S);170 f->source = LoadString(S);
163 n=LoadInt(S);171 n = LoadInt(S);
164 f->lineinfo=luaM_newvector(S->L,n,int);172 f->lineinfo = luaM_newvector(S->L, n, int);
165 f->sizelineinfo=n;173 f->sizelineinfo = n;
166 LoadVector(S,f->lineinfo,n,sizeof(int));174 LoadVector(S, f->lineinfo, n);
167 n=LoadInt(S);175 n = LoadInt(S);
168 f->locvars=luaM_newvector(S->L,n,LocVar);176 f->locvars = luaM_newvector(S->L, n, LocVar);
169 f->sizelocvars=n;177 f->sizelocvars = n;
170 for (i=0; i<n; i++) f->locvars[i].varname=NULL;178 for (i = 0; i < n; i++)
171 for (i=0; i<n; i++)179 f->locvars[i].varname = NULL;
172 {180 for (i = 0; i < n; i++) {
173 f->locvars[i].varname=LoadString(S);181 f->locvars[i].varname = LoadString(S);
174 f->locvars[i].startpc=LoadInt(S);182 f->locvars[i].startpc = LoadInt(S);
175 f->locvars[i].endpc=LoadInt(S);183 f->locvars[i].endpc = LoadInt(S);
176 }184 }
177 n=LoadInt(S);185 n = LoadInt(S);
178 for (i=0; i<n; i++) f->upvalues[i].name=LoadString(S);186 for (i = 0; i < n; i++)
187 f->upvalues[i].name = LoadString(S);
179}188}
180 189
181static void LoadFunction(LoadState* S, Proto* f)190
182{191static void LoadFunction (LoadState *S, Proto *f) {
183 f->linedefined=LoadInt(S);192 f->linedefined = LoadInt(S);
184 f->lastlinedefined=LoadInt(S);193 f->lastlinedefined = LoadInt(S);
185 f->numparams=LoadByte(S);194 f->numparams = LoadByte(S);
186 f->is_vararg=LoadByte(S);195 f->is_vararg = LoadByte(S);
187 f->maxstacksize=LoadByte(S);196 f->maxstacksize = LoadByte(S);
188 LoadCode(S,f);197 LoadCode(S, f);
189 LoadConstants(S,f);198 LoadConstants(S, f);
190 LoadUpvalues(S,f);199 LoadUpvalues(S, f);
191 LoadDebug(S,f);200 LoadDebug(S, f);
192}201}
193 202
194/* the code below must be consistent with the code in luaU_header */203
195#define N0 LUAC_HEADERSIZE204static void checkliteral (LoadState *S, const char *s, const char *msg) {
196#define N1 (sizeof(LUA_SIGNATURE)-sizeof(char))205 char buff[sizeof(LUA_SIGNATURE) + sizeof(LUAC_DATA)]; /* larger than both */
197#define N2 N1+2206 int len = strlen(s);
198#define N3 N2+6207 LoadVector(S, buff, len);
199 208 if (memcmp(s, buff, len) != 0)
200static void LoadHeader(LoadState* S)209 error(S, msg);
201{
202 lu_byte h[LUAC_HEADERSIZE];
203 lu_byte s[LUAC_HEADERSIZE];
204 luaU_header(h);
205 memcpy(s,h,sizeof(char)); /* first char already read */
206 LoadBlock(S,s+sizeof(char),LUAC_HEADERSIZE-sizeof(char));
207 if (memcmp(h,s,N0)==0) return;
208 if (memcmp(h,s,N1)!=0) error(S,"not a");
209 if (memcmp(h,s,N2)!=0) error(S,"version mismatch in");
210 if (memcmp(h,s,N3)!=0) error(S,"incompatible"); else error(S,"corrupted");
211}210}
212 211
213/*212
214** load precompiled chunk213static void fchecksize (LoadState *S, size_t size, const char *tname) {
215*/214 if (LoadByte(S) != size)
216Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)215 error(S, luaO_pushfstring(S->L, "%s size mismatch in", tname));
217{216}
218 LoadState S;217
219 Closure* cl;218
220 if (*name=='@' || *name=='=')219#define checksize(S,t) fchecksize(S,sizeof(t),#t)
221 S.name=name+1;220
222 else if (*name==LUA_SIGNATURE[0])221static void checkHeader (LoadState *S) {
223 S.name="binary string";222 checkliteral(S, LUA_SIGNATURE + 1, "not a"); /* 1st char already checked */
224 else223 if (LoadByte(S) != LUAC_VERSION)
225 S.name=name;224 error(S, "version mismatch in");
226 S.L=L;225 if (LoadByte(S) != LUAC_FORMAT)
227 S.Z=Z;226 error(S, "format mismatch in");
228 S.b=buff;227 checkliteral(S, LUAC_DATA, "corrupted");
229 LoadHeader(&S);228 checksize(S, int);
230 cl=luaF_newLclosure(L,1);229 checksize(S, size_t);
231 setclLvalue(L,L->top,cl); incr_top(L);230 checksize(S, Instruction);
232 cl->l.p=luaF_newproto(L);231 checksize(S, lua_Integer);
233 LoadFunction(&S,cl->l.p);232 checksize(S, lua_Number);
234 if (cl->l.p->sizeupvalues != 1)233 if (LoadInteger(S) != LUAC_INT)
235 {234 error(S, "endianess mismatch in");
236 Proto* p=cl->l.p;235 if (LoadNumber(S) != LUAC_NUM)
237 cl=luaF_newLclosure(L,cl->l.p->sizeupvalues);236 error(S, "float format mismatch in");
238 cl->l.p=p;
239 setclLvalue(L,L->top-1,cl);
240 }
241 luai_verifycode(L,buff,cl->l.p);
242 return cl;
243}237}
244 238
245#define MYINT(s) (s[0]-'0')
246#define VERSION MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)
247#define FORMAT 0 /* this is the official format */
248 239
249/*240/*
250* make header for precompiled chunks241** load precompiled chunk
251* if you change the code below be sure to update LoadHeader and FORMAT above
252* and LUAC_HEADERSIZE in lundump.h
253*/242*/
254void luaU_header (lu_byte* h)243Closure *luaU_undump(lua_State *L, ZIO *Z, Mbuffer *buff,
255{244 const char *name) {
256 int x=1;245 LoadState S;
257 memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-sizeof(char));246 Closure *cl;
258 h+=sizeof(LUA_SIGNATURE)-sizeof(char);247 if (*name == '@' || *name == '=')
259 *h++=cast_byte(VERSION);248 S.name = name + 1;
260 *h++=cast_byte(FORMAT);249 else if (*name == LUA_SIGNATURE[0])
261 *h++=cast_byte(*(char*)&x); /* endianness */250 S.name = "binary string";
262 *h++=cast_byte(sizeof(int));251 else
263 *h++=cast_byte(sizeof(size_t));252 S.name = name;
264 *h++=cast_byte(sizeof(Instruction));253 S.L = L;
265 *h++=cast_byte(sizeof(lua_Number));254 S.Z = Z;
266 *h++=cast_byte(((lua_Number)0.5)==0); /* is lua_Number integral? */255 S.b = buff;
267 memcpy(h,LUAC_TAIL,sizeof(LUAC_TAIL)-sizeof(char));256 checkHeader(&S);
257 cl = luaF_newLclosure(L, LoadByte(&S));
258 setclLvalue(L, L->top, cl);
259 incr_top(L);
260 cl->l.p = luaF_newproto(L);
261 LoadFunction(&S, cl->l.p);
262 lua_assert(cl->l.nupvalues == cl->l.p->sizeupvalues);
263 luai_verifycode(L, buff, cl->l.p);
264 return cl;
268}265}
266
src/lundump.h+16−11
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lundump.h,v 1.39 2012/05/08 13:53:33 roberto Exp $2** $Id: lundump.h,v 1.42 2014/03/11 14:22:54 roberto Exp $
3** load precompiled Lua chunks3** load precompiled Lua chunks
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -7,22 +7,27 @@ · 1 unmodified line
7#ifndef lundump_h7#ifndef lundump_h
8#define lundump_h8#define lundump_h
9 9
10#include "llimits.h"
10#include "lobject.h"11#include "lobject.h"
11#include "lzio.h"12#include "lzio.h"
12 13
13/* load one chunk; from lundump.c */
14LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
15 14
16/* make header; from lundump.c */15/* data to catch conversion errors */
17LUAI_FUNC void luaU_header (lu_byte* h);16#define LUAC_DATA "\x19\x93\r\n\x1a\n"
18 17
19/* dump one chunk; from ldump.c */18#define LUAC_INT cast_integer(0xABCD)
20LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);19#define LUAC_NUM cast_num(370.5)
21 20
22/* data to catch conversion errors */21#define MYINT(s) (s[0]-'0')
23#define LUAC_TAIL "\x19\x93\r\n\x1a\n"22#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR))
23#define LUAC_FORMAT 0 /* this is the official format */
24 24
25/* size in bytes of header of binary files */25/* load one chunk; from lundump.c */
26#define LUAC_HEADERSIZE (sizeof(LUA_SIGNATURE)-sizeof(char)+2+6+sizeof(LUAC_TAIL)-sizeof(char))26LUAI_FUNC Closure* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff,
27 const char* name);
28
29/* dump one chunk; from ldump.c */
30LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w,
31 void* data, int strip);
27 32
28#endif33#endif
src/lutf8lib.c+240−0
@@ -0,0 +1,240 @@
1/*
2** $Id: lutf8lib.c,v 1.4 2014/03/20 19:36:02 roberto Exp $
3** Standard library for UTF-8 manipulation
4** See Copyright Notice in lua.h
5*/
6
7
8#include <assert.h>
9#include <stdlib.h>
10#include <string.h>
11
12#define lutf8lib_c
13#define LUA_LIB
14
15#include "lua.h"
16
17#include "lauxlib.h"
18#include "lualib.h"
19
20#define MAXUNICODE 0x10FFFF
21
22#define iscont(p) ((*(p) & 0xC0) == 0x80)
23
24
25/* from strlib */
26/* translate a relative string position: negative means back from end */
27static lua_Integer u_posrelat (lua_Integer pos, size_t len) {
28 if (pos >= 0) return pos;
29 else if (0u - (size_t)pos > len) return 0;
30 else return (lua_Integer)len + pos + 1;
31}
32
33
34/*
35** Decode an UTF-8 sequence, returning NULL if byte sequence is invalid.
36*/
37static const char *utf8_decode (const char *o, int *val) {
38 static unsigned int limits[] = {0xFF, 0x7F, 0x7FF, 0xFFFF};
39 const unsigned char *s = (const unsigned char *)o;
40 unsigned int c = s[0];
41 unsigned int res = 0; /* final result */
42 if (c < 0x80) /* ascii? */
43 res = c;
44 else {
45 int count = 0; /* to count number of continuation bytes */
46 while (c & 0x40) { /* still have continuation bytes? */
47 int cc = s[++count]; /* read next byte */
48 if ((cc & 0xC0) != 0x80) /* not a continuation byte? */
49 return NULL; /* invalid byte sequence */
50 res = (res << 6) | (cc & 0x3F); /* add lower 6 bits from cont. byte */
51 c <<= 1; /* to test next bit */
52 }
53 res |= ((c & 0x7F) << (count * 5)); /* add first byte */
54 if (count > 3 || res > MAXUNICODE || res <= limits[count])
55 return NULL; /* invalid byte sequence */
56 s += count; /* skip continuation bytes read */
57 }
58 if (val) *val = res;
59 return (const char *)s + 1; /* +1 to include first byte */
60}
61
62
63/*
64** utf8len(s, [i]) --> number of codepoints in 's' after 'i';
65** nil if 's' not well formed
66*/
67static int utflen (lua_State *L) {
68 int n = 0;
69 const char *ends;
70 size_t len;
71 const char *s = luaL_checklstring(L, 1, &len);
72 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), 1);
73 luaL_argcheck(L, 1 <= posi && posi <= (lua_Integer)len, 1,
74 "initial position out of string");
75 ends = s + len;
76 s += posi - 1;
77 while (s < ends && (s = utf8_decode(s, NULL)) != NULL)
78 n++;
79 if (s == ends)
80 lua_pushinteger(L, n);
81 else
82 lua_pushnil(L);
83 return 1;
84}
85
86
87/*
88** codepoint(s, [i, [j]]) -> returns codepoints for all characters
89** between i and j
90*/
91static int codepoint (lua_State *L) {
92 size_t len;
93 const char *s = luaL_checklstring(L, 1, &len);
94 lua_Integer posi = u_posrelat(luaL_optinteger(L, 2, 1), len);
95 lua_Integer pose = u_posrelat(luaL_optinteger(L, 3, posi), len);
96 int n;
97 const char *se;
98 luaL_argcheck(L, posi >= 1, 2, "out of range");
99 luaL_argcheck(L, pose <= (lua_Integer)len, 3, "out of range");
100 if (posi > pose) return 0; /* empty interval; return no values */
101 n = (int)(pose - posi + 1);
102 if (posi + n <= pose) /* (lua_Integer -> int) overflow? */
103 return luaL_error(L, "string slice too long");
104 luaL_checkstack(L, n, "string slice too long");
105 n = 0;
106 se = s + pose;
107 for (s += posi - 1; s < se;) {
108 int code;
109 s = utf8_decode(s, &code);
110 if (s == NULL)
111 return luaL_error(L, "invalid UTF-8 code");
112 lua_pushinteger(L, code);
113 n++;
114 }
115 return n;
116}
117
118
119static void pushutfchar (lua_State *L, int arg) {
120 int code = luaL_checkint(L, arg);
121 luaL_argcheck(L, 0 <= code && code <= MAXUNICODE, arg, "value out of range");
122 lua_pushfstring(L, "%U", code);
123}
124
125
126/*
127** utfchar(n1, n2, ...) -> char(n1)..char(n2)...
128*/
129static int utfchar (lua_State *L) {
130 int n = lua_gettop(L); /* number of arguments */
131 if (n == 1) /* optimize common case of single char */
132 pushutfchar(L, 1);
133 else {
134 int i;
135 luaL_Buffer b;
136 luaL_buffinit(L, &b);
137 for (i = 1; i <= n; i++) {
138 pushutfchar(L, i);
139 luaL_addvalue(&b);
140 }
141 luaL_pushresult(&b);
142 }
143 return 1;
144}
145
146
147/*
148** offset(s, n, [i]) -> index where n-th character *after*
149** position 'i' starts; 0 means character at 'i'.
150*/
151static int byteoffset (lua_State *L) {
152 size_t len;
153 const char *s = luaL_checklstring(L, 1, &len);
154 int n = luaL_checkint(L, 2);
155 lua_Integer posi = u_posrelat(luaL_optinteger(L, 3, 1), len) - 1;
156 luaL_argcheck(L, 0 <= posi && posi <= (lua_Integer)len, 3,
157 "position out of range");
158 if (n == 0) {
159 /* find beginning of current byte sequence */
160 while (posi > 0 && iscont(s + posi)) posi--;
161 }
162 else if (n < 0) {
163 while (n < 0 && posi > 0) { /* move back */
164 do { /* find beginning of previous character */
165 posi--;
166 } while (posi > 0 && iscont(s + posi));
167 n++;
168 }
169 }
170 else {
171 n--; /* do not move for 1st character */
172 while (n > 0 && posi < (lua_Integer)len) {
173 do { /* find beginning of next character */
174 posi++;
175 } while (iscont(s + posi)); /* ('\0' is not continuation) */
176 n--;
177 }
178 }
179 if (n == 0)
180 lua_pushinteger(L, posi + 1);
181 else
182 lua_pushnil(L); /* no such position */
183 return 1;
184}
185
186
187static int iter_aux (lua_State *L) {
188 size_t len;
189 const char *s = luaL_checklstring(L, 1, &len);
190 int n = lua_tointeger(L, 2) - 1;
191 if (n < 0) /* first iteration? */
192 n = 0; /* start from here */
193 else if (n < (lua_Integer)len) {
194 n++; /* skip current byte */
195 while (iscont(s + n)) n++; /* and its continuations */
196 }
197 if (n >= (lua_Integer)len)
198 return 0; /* no more codepoints */
199 else {
200 int code;
201 const char *next = utf8_decode(s + n, &code);
202 if (next == NULL || iscont(next))
203 return luaL_error(L, "invalid UTF-8 code");
204 lua_pushinteger(L, n + 1);
205 lua_pushinteger(L, code);
206 return 2;
207 }
208}
209
210
211static int iter_codes (lua_State *L) {
212 luaL_checkstring(L, 1);
213 lua_pushcfunction(L, iter_aux);
214 lua_pushvalue(L, 1);
215 lua_pushinteger(L, 0);
216 return 3;
217}
218
219
220/* pattern to match a single UTF-8 character */
221#define UTF8PATT "[\0-\x7F\xC2-\xF4][\x80-\xBF]*"
222
223
224static struct luaL_Reg funcs[] = {
225 {"offset", byteoffset},
226 {"codepoint", codepoint},
227 {"char", utfchar},
228 {"len", utflen},
229 {"codes", iter_codes},
230 {NULL, NULL}
231};
232
233
234int luaopen_utf8 (lua_State *L) {
235 luaL_newlib(L, funcs);
236 lua_pushliteral(L, UTF8PATT);
237 lua_setfield(L, -2, "charpatt");
238 return 1;
239}
240
src/lvm.c+125−56
@@ -1,10 +1,11 @@
1/*1/*
2** $Id: lvm.c,v 2.175 2013/06/20 15:02:49 roberto Exp $2** $Id: lvm.c,v 2.190 2014/03/15 12:29:48 roberto Exp $
3** Lua virtual machine3** Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
6 6
7 7
8#include <limits.h>
8#include <stdio.h>9#include <stdio.h>
9#include <stdlib.h>10#include <stdlib.h>
10#include <string.h>11#include <string.h>
@@ -29,7 +30,7 @@ · 18 unmodified lines
29 30
30 31
31/* limit for table tag-method chains (to avoid loops) */32/* limit for table tag-method chains (to avoid loops) */
32#define MAXTAGLOOP 10033#define MAXTAGLOOP 2000
33 34
34 35
35/* maximum length of the conversion of a number to a string */36/* maximum length of the conversion of a number to a string */
@@ -52,17 +53,9 @@ int luaV_tostring (lua_State *L, StkId obj) { · 16 unmodified lines
52 return 0;53 return 0;
53 else {54 else {
54 char buff[MAXNUMBER2STR];55 char buff[MAXNUMBER2STR];
55 size_t len;56 size_t len = (ttisinteger(obj))
56 if (ttisinteger(obj))57 ? lua_integer2str(buff, ivalue(obj))
57 len = lua_integer2str(buff, ivalue(obj));58 : lua_number2str(buff, fltvalue(obj));
58 else {
59 len = lua_number2str(buff, fltvalue(obj));
60 if (strspn(buff, "-0123456789") == len) { /* look like an integer? */
61 buff[len++] = '.'; /* add a '.0' */
62 buff[len++] = '0';
63 buff[len] = '\0';
64 }
65 }
66 setsvalue2s(L, obj, luaS_newlstr(L, buff, len));59 setsvalue2s(L, obj, luaS_newlstr(L, buff, len));
67 return 1;60 return 1;
68 }61 }
@@ -73,7 +66,7 @@ int luaV_tostring (lua_State *L, StkId obj) { · 4 unmodified lines
73** Check whether a float number is within the range of a lua_Integer.66** Check whether a float number is within the range of a lua_Integer.
74** (The comparisons are tricky because of rounding, which can or67** (The comparisons are tricky because of rounding, which can or
75** not occur depending on the relative sizes of floats and integers.)68** not occur depending on the relative sizes of floats and integers.)
76** This function is called only when 'n' has an integer value.69** This function should be called only when 'n' has an integral value.
77*/70*/
78int luaV_numtointeger (lua_Number n, lua_Integer *p) {71int luaV_numtointeger (lua_Number n, lua_Integer *p) {
79 if (cast_num(MIN_INTEGER) <= n && n < (MAX_INTEGER + cast_num(1))) {72 if (cast_num(MIN_INTEGER) <= n && n < (MAX_INTEGER + cast_num(1))) {
@@ -121,7 +114,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 41 unmodified lines
121 }114 }
122 t = tm; /* else repeat with 'tm' */115 t = tm; /* else repeat with 'tm' */
123 }116 }
124 luaG_runerror(L, "loop in gettable");117 luaG_runerror(L, "gettable chain too long; possible loop");
125}118}
126 119
127 120
@@ -145,7 +138,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 17 unmodified lines
145 /* no metamethod and (now) there is an entry with given key */138 /* no metamethod and (now) there is an entry with given key */
146 setobj2t(L, oldval, val); /* assign new value to that entry */139 setobj2t(L, oldval, val); /* assign new value to that entry */
147 invalidateTMcache(h);140 invalidateTMcache(h);
148 luaC_barrierback(L, obj2gco(h), val);141 luaC_barrierback(L, h, val);
149 return;142 return;
150 }143 }
151 /* else will try the metamethod */144 /* else will try the metamethod */
@@ -160,7 +153,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { · 8 unmodified lines
160 }153 }
161 t = tm; /* else repeat with 'tm' */154 t = tm; /* else repeat with 'tm' */
162 }155 }
163 luaG_runerror(L, "loop in settable");156 luaG_runerror(L, "settable chain too long; possible loop");
164}157}
165 158
166 159
@@ -192,7 +185,7 @@ int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r) { · 25 unmodified lines
192 if (ttisinteger(l) && ttisinteger(r))185 if (ttisinteger(l) && ttisinteger(r))
193 return (ivalue(l) < ivalue(r));186 return (ivalue(l) < ivalue(r));
194 else if (tonumber(l, &nl) && tonumber(r, &nr))187 else if (tonumber(l, &nl) && tonumber(r, &nr))
195 return luai_numlt(L, nl, nr);188 return luai_numlt(nl, nr);
196 else if (ttisstring(l) && ttisstring(r))189 else if (ttisstring(l) && ttisstring(r))
197 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;190 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) < 0;
198 else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)191 else if ((res = luaT_callorderTM(L, l, r, TM_LT)) < 0)
@@ -207,7 +200,7 @@ int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r) { · 8 unmodified lines
207 if (ttisinteger(l) && ttisinteger(r))200 if (ttisinteger(l) && ttisinteger(r))
208 return (ivalue(l) <= ivalue(r));201 return (ivalue(l) <= ivalue(r));
209 else if (tonumber(l, &nl) && tonumber(r, &nr))202 else if (tonumber(l, &nl) && tonumber(r, &nr))
210 return luai_numle(L, nl, nr);203 return luai_numle(nl, nr);
211 else if (ttisstring(l) && ttisstring(r))204 else if (ttisstring(l) && ttisstring(r))
212 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;205 return l_strcmp(rawtsvalue(l), rawtsvalue(r)) <= 0;
213 else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */206 else if ((res = luaT_callorderTM(L, l, r, TM_LE)) >= 0) /* first try `le' */
@@ -229,7 +222,7 @@ int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2) { · 15 unmodified lines
229 else { /* two numbers with different variants */222 else { /* two numbers with different variants */
230 lua_Number n1, n2;223 lua_Number n1, n2;
231 lua_assert(ttisnumber(t1) && ttisnumber(t2));224 lua_assert(ttisnumber(t1) && ttisnumber(t2));
232 (void)tonumber(t1, &n1); (void)tonumber(t2, &n2);225 cast_void(tonumber(t1, &n1)); cast_void(tonumber(t2, &n2));
233 return luai_numeq(n1, n2);226 return luai_numeq(n1, n2);
234 }227 }
235 }228 }
@@ -272,7 +265,7 @@ void luaV_concat (lua_State *L, int total) { · 36 unmodified lines
272 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1))265 if (!(ttisstring(top-2) || ttisnumber(top-2)) || !tostring(L, top-1))
273 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);266 luaT_trybinTM(L, top-2, top-1, top-2, TM_CONCAT);
274 else if (tsvalue(top-1)->len == 0) /* second operand is empty? */267 else if (tsvalue(top-1)->len == 0) /* second operand is empty? */
275 (void)tostring(L, top - 2); /* result is first operand */268 cast_void(tostring(L, top - 2)); /* result is first operand */
276 else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {269 else if (ttisstring(top-2) && tsvalue(top-2)->len == 0) {
277 setobjs2s(L, top - 2, top - 1); /* result is second op. */270 setobjs2s(L, top - 2, top - 1); /* result is second op. */
278 }271 }
@@ -333,8 +326,7 @@ lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y) { · 54 unmodified lines
333 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */326 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
334 if (y == 0)327 if (y == 0)
335 luaG_runerror(L, "attempt to divide by zero");328 luaG_runerror(L, "attempt to divide by zero");
336 else /* -1 */329 return intop(-, 0, x); /* y==-1; avoid overflow with 0x80000...//-1 */
337 return -x; /* avoid overflow with 0x80000... */
338 }330 }
339 else {331 else {
340 lua_Integer d = x / y; /* perform division */332 lua_Integer d = x / y; /* perform division */
@@ -350,8 +342,7 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) { · 9 unmodified lines
350 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */342 if (cast_unsigned(y) + 1 <= 1U) { /* special cases: -1 or 0 */
351 if (y == 0)343 if (y == 0)
352 luaG_runerror(L, "attempt to perform 'n%%0'");344 luaG_runerror(L, "attempt to perform 'n%%0'");
353 else /* -1 */345 return 0; /* y==-1; avoid overflow with 0x80000...%-1 */
354 return 0; /* avoid overflow with 0x80000... */
355 }346 }
356 else {347 else {
357 lua_Integer r = x % y;348 lua_Integer r = x % y;
@@ -363,16 +354,36 @@ lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y) { · 5 unmodified lines
363}354}
364 355
365 356
366lua_Integer luaV_pow (lua_Integer x, lua_Integer y) {357lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y) {
367 lua_Integer r = 1;358 if (y <= 0) { /* special cases: 0 or negative exponent */
368 lua_assert(y >= 0);359 if (y < 0)
369 if (y == 0) return r;360 luaG_runerror(L, "integer exponentiation with negative exponent");
370 for (; y > 1; y >>= 1) {361 return 1; /* x^0 == 1 */
371 if (y & 1) r = intop(*, r, x);362 }
372 x = intop(*, x, x);363 else {
364 lua_Integer r = 1;
365 for (; y > 1; y >>= 1) {
366 if (y & 1) r = intop(*, r, x);
367 x = intop(*, x, x);
368 }
369 r = intop(*, r, x);
370 return r;
371 }
372}
373
374
375/* number of bits in an integer */
376#define NBITS cast_int(sizeof(lua_Integer) * CHAR_BIT)
377
378LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y) {
379 if (y < 0) { /* shift right? */
380 if (y <= -NBITS) return 0;
381 else return cast_integer(cast_unsigned(x) >> (-y));
382 }
383 else { /* shift left */
384 if (y >= NBITS) return 0;
385 else return x << y;
373 }386 }
374 r = intop(*, r, x);
375 return r;
376}387}
377 388
378 389
@@ -399,9 +410,9 @@ static Closure *getcached (Proto *p, UpVal **encup, StkId base) { · 20 unmodified lines
399 410
400/*411/*
401** create a new Lua closure, push it in the stack, and initialize412** create a new Lua closure, push it in the stack, and initialize
402** its upvalues. Note that the call to 'luaC_barrierproto' must come413** its upvalues. Note that the closure is not cached if prototype is
403** before the assignment to 'p->cache', as the function needs the414** already black (which means that 'cache' was already cleared by the
404** original value of that field.415** GC).
405*/416*/
406static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,417static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base,
407 StkId ra) {418 StkId ra) {
@@ -416,9 +427,11 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, · 8 unmodified lines
416 ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);427 ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx);
417 else /* get upvalue from enclosing function */428 else /* get upvalue from enclosing function */
418 ncl->l.upvals[i] = encup[uv[i].idx];429 ncl->l.upvals[i] = encup[uv[i].idx];
430 ncl->l.upvals[i]->refcount++;
431 /* new closure is white, so we do not need a barrier here */
419 }432 }
420 luaC_barrierproto(L, p, ncl);433 if (!isblack(obj2gco(p))) /* cache will not break GC invariant? */
421 p->cache = ncl; /* save it on cache for reuse */434 p->cache = ncl; /* save it on cache for reuse */
422}435}
423 436
424 437
@@ -432,7 +445,9 @@ void luaV_finishOp (lua_State *L) { · 7 unmodified lines
432 OpCode op = GET_OPCODE(inst);445 OpCode op = GET_OPCODE(inst);
433 switch (op) { /* finish its execution */446 switch (op) { /* finish its execution */
434 case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:447 case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_IDIV:
435 case OP_MOD: case OP_POW: case OP_UNM: case OP_LEN:448 case OP_BAND: case OP_BOR: case OP_BXOR: case OP_SHL: case OP_SHR:
449 case OP_MOD: case OP_POW:
450 case OP_UNM: case OP_BNOT: case OP_LEN:
436 case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {451 case OP_GETTABUP: case OP_GETTABLE: case OP_SELF: {
437 setobjs2s(L, base + GETARG_A(inst), --L->top);452 setobjs2s(L, base + GETARG_A(inst), --L->top);
438 break;453 break;
@@ -590,7 +605,7 @@ void luaV_execute (lua_State *L) { · 151 unmodified lines
590 vmcase(OP_SETUPVAL,605 vmcase(OP_SETUPVAL,
591 UpVal *uv = cl->upvals[GETARG_B(i)];606 UpVal *uv = cl->upvals[GETARG_B(i)];
592 setobj(L, uv->v, ra);607 setobj(L, uv->v, ra);
593 luaC_barrier(L, uv, ra);608 luaC_upvalbarrier(L, uv);
594 )609 )
595 vmcase(OP_SETTABLE,610 vmcase(OP_SETTABLE,
596 Protect(luaV_settable(L, ra, RKB(i), RKC(i)));611 Protect(luaV_settable(L, ra, RKB(i), RKC(i)));
@@ -666,6 +681,51 @@ void luaV_execute (lua_State *L) { · 69 unmodified lines
666 }681 }
667 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); }682 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_IDIV)); }
668 )683 )
684 vmcase(OP_BAND,
685 TValue *rb = RKB(i);
686 TValue *rc = RKC(i);
687 lua_Integer ib; lua_Integer ic;
688 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
689 setivalue(ra, intop(&, ib, ic));
690 }
691 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BAND)); }
692 )
693 vmcase(OP_BOR,
694 TValue *rb = RKB(i);
695 TValue *rc = RKC(i);
696 lua_Integer ib; lua_Integer ic;
697 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
698 setivalue(ra, intop(|, ib, ic));
699 }
700 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BOR)); }
701 )
702 vmcase(OP_BXOR,
703 TValue *rb = RKB(i);
704 TValue *rc = RKC(i);
705 lua_Integer ib; lua_Integer ic;
706 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
707 setivalue(ra, intop(^, ib, ic));
708 }
709 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_BXOR)); }
710 )
711 vmcase(OP_SHL,
712 TValue *rb = RKB(i);
713 TValue *rc = RKC(i);
714 lua_Integer ib; lua_Integer ic;
715 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
716 setivalue(ra, luaV_shiftl(ib, ic));
717 }
718 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHL)); }
719 )
720 vmcase(OP_SHR,
721 TValue *rb = RKB(i);
722 TValue *rc = RKC(i);
723 lua_Integer ib; lua_Integer ic;
724 if (tointeger(rb, &ib) && tointeger(rc, &ic)) {
725 setivalue(ra, luaV_shiftl(ib, -ic));
726 }
727 else { Protect(luaT_trybinTM(L, rb, rc, ra, TM_SHR)); }
728 )
669 vmcase(OP_MOD,729 vmcase(OP_MOD,
670 TValue *rb = RKB(i);730 TValue *rb = RKB(i);
671 TValue *rc = RKC(i);731 TValue *rc = RKC(i);
@@ -683,11 +743,9 @@ void luaV_execute (lua_State *L) { · 11 unmodified lines
683 TValue *rb = RKB(i);743 TValue *rb = RKB(i);
684 TValue *rc = RKC(i);744 TValue *rc = RKC(i);
685 lua_Number nb; lua_Number nc;745 lua_Number nb; lua_Number nc;
686 lua_Integer ic;746 if (ttisinteger(rb) && ttisinteger(rc)) {
687 if (ttisinteger(rb) && ttisinteger(rc) &&747 lua_Integer ib = ivalue(rb); lua_Integer ic = ivalue(rc);
688 (ic = ivalue(rc)) >= 0) {748 setivalue(ra, luaV_pow(L, ib, ic));
689 lua_Integer ib = ivalue(rb);
690 setivalue(ra, luaV_pow(ib, ic));
691 }749 }
692 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {750 else if (tonumber(rb, &nb) && tonumber(rc, &nc)) {
693 setnvalue(ra, luai_numpow(L, nb, nc));751 setnvalue(ra, luai_numpow(L, nb, nc));
@@ -699,7 +757,7 @@ void luaV_execute (lua_State *L) { · 5 unmodified lines
699 lua_Number nb;757 lua_Number nb;
700 if (ttisinteger(rb)) {758 if (ttisinteger(rb)) {
701 lua_Integer ib = ivalue(rb);759 lua_Integer ib = ivalue(rb);
702 setivalue(ra, -ib);760 setivalue(ra, intop(-, 0, ib));
703 }761 }
704 else if (tonumber(rb, &nb)) {762 else if (tonumber(rb, &nb)) {
705 setnvalue(ra, luai_numunm(L, nb));763 setnvalue(ra, luai_numunm(L, nb));
@@ -708,6 +766,16 @@ void luaV_execute (lua_State *L) { · 2 unmodified lines
708 Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));766 Protect(luaT_trybinTM(L, rb, rb, ra, TM_UNM));
709 }767 }
710 )768 )
769 vmcase(OP_BNOT,
770 TValue *rb = RB(i);
771 lua_Integer ib;
772 if (tointeger(rb, &ib)) {
773 setivalue(ra, intop(^, cast_integer(-1), ib));
774 }
775 else {
776 Protect(luaT_trybinTM(L, rb, rb, ra, TM_BNOT));
777 }
778 )
711 vmcase(OP_NOT,779 vmcase(OP_NOT,
712 TValue *rb = RB(i);780 TValue *rb = RB(i);
713 int res = l_isfalse(rb); /* next assignment may change this value */781 int res = l_isfalse(rb); /* next assignment may change this value */
@@ -831,7 +899,7 @@ void luaV_execute (lua_State *L) { · 117 unmodified lines
831 }899 }
832 )900 )
833 vmcase(OP_FORLOOP,901 vmcase(OP_FORLOOP,
834 if (ttisinteger(ra)) { /* integer count? */902 if (ttisinteger(ra)) { /* integer loop? */
835 lua_Integer step = ivalue(ra + 2);903 lua_Integer step = ivalue(ra + 2);
836 lua_Integer idx = ivalue(ra) + step; /* increment index */904 lua_Integer idx = ivalue(ra) + step; /* increment index */
837 lua_Integer limit = ivalue(ra + 1);905 lua_Integer limit = ivalue(ra + 1);
@@ -841,12 +909,12 @@ void luaV_execute (lua_State *L) { · 3 unmodified lines
841 setivalue(ra + 3, idx); /* ...and external index */909 setivalue(ra + 3, idx); /* ...and external index */
842 }910 }
843 }911 }
844 else { /* floating count */912 else { /* floating loop */
845 lua_Number step = fltvalue(ra + 2);913 lua_Number step = fltvalue(ra + 2);
846 lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */914 lua_Number idx = luai_numadd(L, fltvalue(ra), step); /* inc. index */
847 lua_Number limit = fltvalue(ra + 1);915 lua_Number limit = fltvalue(ra + 1);
848 if (luai_numlt(L, 0, step) ? luai_numle(L, idx, limit)916 if (luai_numlt(0, step) ? luai_numle(idx, limit)
849 : luai_numle(L, limit, idx)) {917 : luai_numle(limit, idx)) {
850 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */918 ci->u.l.savedpc += GETARG_sBx(i); /* jump back */
851 setnvalue(ra, idx); /* update internal index... */919 setnvalue(ra, idx); /* update internal index... */
852 setnvalue(ra + 3, idx); /* ...and external index */920 setnvalue(ra + 3, idx); /* ...and external index */
@@ -857,10 +925,11 @@ void luaV_execute (lua_State *L) { · 4 unmodified lines
857 TValue *init = ra;925 TValue *init = ra;
858 TValue *plimit = ra + 1;926 TValue *plimit = ra + 1;
859 TValue *pstep = ra + 2;927 TValue *pstep = ra + 2;
860 if (ttisinteger(ra) && ttisinteger(ra + 1) && ttisinteger(ra + 2)) {928 if (ttisinteger(init) && ttisinteger(plimit) && ttisinteger(pstep)) {
861 setivalue(ra, ivalue(ra) - ivalue(pstep));929 /* all values are integer */
930 setivalue(init, ivalue(init) - ivalue(pstep));
862 }931 }
863 else { /* try with floats */932 else { /* try making all values floats */
864 lua_Number ninit; lua_Number nlimit; lua_Number nstep;933 lua_Number ninit; lua_Number nlimit; lua_Number nstep;
865 if (!tonumber(plimit, &nlimit))934 if (!tonumber(plimit, &nlimit))
866 luaG_runerror(L, LUA_QL("for") " limit must be a number");935 luaG_runerror(L, LUA_QL("for") " limit must be a number");
@@ -870,7 +939,7 @@ void luaV_execute (lua_State *L) { · 3 unmodified lines
870 setnvalue(pstep, nstep);939 setnvalue(pstep, nstep);
871 if (!tonumber(init, &ninit))940 if (!tonumber(init, &ninit))
872 luaG_runerror(L, LUA_QL("for") " initial value must be a number");941 luaG_runerror(L, LUA_QL("for") " initial value must be a number");
873 setnvalue(ra, luai_numsub(L, ninit, nstep));942 setnvalue(init, luai_numsub(L, ninit, nstep));
874 }943 }
875 ci->u.l.savedpc += GETARG_sBx(i);944 ci->u.l.savedpc += GETARG_sBx(i);
876 )945 )
@@ -912,7 +981,7 @@ void luaV_execute (lua_State *L) { · 35 unmodified lines
912 for (; n > 0; n--) {981 for (; n > 0; n--) {
913 TValue *val = ra+n;982 TValue *val = ra+n;
914 luaH_setint(L, h, last--, val);983 luaH_setint(L, h, last--, val);
915 luaC_barrierback(L, obj2gco(h), val);984 luaC_barrierback(L, h, val);
916 }985 }
917 L->top = ci->top; /* correct top (in case of previous open call) */986 L->top = ci->top; /* correct top (in case of previous open call) */
918 )987 )
src/lvm.h+3−2
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lvm.h,v 2.23 2013/05/02 12:31:26 roberto Exp $2** $Id: lvm.h,v 2.25 2013/12/30 20:47:58 roberto Exp $
3** Lua virtual machine3** Lua virtual machine
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -43,7 +43,8 @@ LUAI_FUNC void luaV_execute (lua_State *L); · 37 unmodified lines
43LUAI_FUNC void luaV_concat (lua_State *L, int total);43LUAI_FUNC void luaV_concat (lua_State *L, int total);
44LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);44LUAI_FUNC lua_Integer luaV_div (lua_State *L, lua_Integer x, lua_Integer y);
45LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);45LUAI_FUNC lua_Integer luaV_mod (lua_State *L, lua_Integer x, lua_Integer y);
46LUAI_FUNC lua_Integer luaV_pow (lua_Integer x, lua_Integer y);46LUAI_FUNC lua_Integer luaV_pow (lua_State *L, lua_Integer x, lua_Integer y);
47LUAI_FUNC lua_Integer luaV_shiftl (lua_Integer x, lua_Integer y);
47LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);48LUAI_FUNC void luaV_objlen (lua_State *L, StkId ra, const TValue *rb);
48 49
49#endif50#endif
src/lzio.h+2−1
@@ -1,5 +1,5 @@
1/*1/*
2** $Id: lzio.h,v 1.27 2013/06/07 14:51:10 roberto Exp $2** $Id: lzio.h,v 1.28 2014/01/31 15:14:22 roberto Exp $
3** Buffered streams3** Buffered streams
4** See Copyright Notice in lua.h4** See Copyright Notice in lua.h
5*/5*/
@@ -32,6 +32,7 @@ typedef struct Mbuffer { · 26 unmodified lines
32#define luaZ_sizebuffer(buff) ((buff)->buffsize)32#define luaZ_sizebuffer(buff) ((buff)->buffsize)
33#define luaZ_bufflen(buff) ((buff)->n)33#define luaZ_bufflen(buff) ((buff)->n)
34 34
35#define luaZ_buffremove(buff,i) ((buff)->n -= (i))
35#define luaZ_resetbuffer(buff) ((buff)->n = 0)36#define luaZ_resetbuffer(buff) ((buff)->n = 0)
36 37
37 38