aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--lapi.c19
-rw-r--r--ltable.c55
-rw-r--r--ltable.h19
-rw-r--r--lvm.h36
4 files changed, 80 insertions, 49 deletions
diff --git a/lapi.c b/lapi.c
index d18445e0..74f1d66b 100644
--- a/lapi.c
+++ b/lapi.c
@@ -102,7 +102,7 @@ static TValue *index2value (lua_State *L, int idx) {
102/* 102/*
103** Convert a valid actual index (not a pseudo-index) to its address. 103** Convert a valid actual index (not a pseudo-index) to its address.
104*/ 104*/
105l_sinline StkId index2stack (lua_State *L, int idx) { 105static StkId index2stack (lua_State *L, int idx) {
106 CallInfo *ci = L->ci; 106 CallInfo *ci = L->ci;
107 if (idx > 0) { 107 if (idx > 0) {
108 StkId o = ci->func.p + idx; 108 StkId o = ci->func.p + idx;
@@ -234,7 +234,7 @@ LUA_API void lua_closeslot (lua_State *L, int idx) {
234** Note that we move(copy) only the value inside the stack. 234** Note that we move(copy) only the value inside the stack.
235** (We do not move additional fields that may exist.) 235** (We do not move additional fields that may exist.)
236*/ 236*/
237l_sinline void reverse (lua_State *L, StkId from, StkId to) { 237static void reverse (lua_State *L, StkId from, StkId to) {
238 for (; from < to; from++, to--) { 238 for (; from < to; from++, to--) {
239 TValue temp; 239 TValue temp;
240 setobj(L, &temp, s2v(from)); 240 setobj(L, &temp, s2v(from));
@@ -664,7 +664,7 @@ LUA_API int lua_pushthread (lua_State *L) {
664*/ 664*/
665 665
666 666
667l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { 667static int auxgetstr (lua_State *L, const TValue *t, const char *k) {
668 int hres; 668 int hres;
669 TString *str = luaS_new(L, k); 669 TString *str = luaS_new(L, k);
670 luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, hres); 670 luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, hres);
@@ -683,7 +683,9 @@ l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
683 683
684static void getGlobalTable (lua_State *L, TValue *gt) { 684static void getGlobalTable (lua_State *L, TValue *gt) {
685 Table *registry = hvalue(&G(L)->l_registry); 685 Table *registry = hvalue(&G(L)->l_registry);
686 luaH_getint(registry, LUA_RIDX_GLOBALS, gt); 686 int hres = luaH_getint(registry, LUA_RIDX_GLOBALS, gt);
687 (void)hres; /* avoid warnings (not used) when checks are off */
688 api_check(L, hres == HOK, "global table must exist");
687} 689}
688 690
689 691
@@ -740,7 +742,7 @@ l_sinline int finishrawget (lua_State *L, int hres) {
740} 742}
741 743
742 744
743static Table *gettable (lua_State *L, int idx) { 745l_sinline Table *gettable (lua_State *L, int idx) {
744 TValue *t = index2value(L, idx); 746 TValue *t = index2value(L, idx);
745 api_check(L, ttistable(t), "table expected"); 747 api_check(L, ttistable(t), "table expected");
746 return hvalue(t); 748 return hvalue(t);
@@ -761,9 +763,11 @@ LUA_API int lua_rawget (lua_State *L, int idx) {
761 763
762LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { 764LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
763 Table *t; 765 Table *t;
766 int hres;
764 lua_lock(L); 767 lua_lock(L);
765 t = gettable(L, idx); 768 t = gettable(L, idx);
766 return finishrawget(L, luaH_getint(t, n, s2v(L->top.p))); 769 luaH_fastgeti(t, n, s2v(L->top.p), hres);
770 return finishrawget(L, hres);
767} 771}
768 772
769 773
@@ -901,9 +905,8 @@ LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
901 api_checknelems(L, 1); 905 api_checknelems(L, 1);
902 t = index2value(L, idx); 906 t = index2value(L, idx);
903 luaV_fastseti(t, n, s2v(L->top.p - 1), hres); 907 luaV_fastseti(t, n, s2v(L->top.p - 1), hres);
904 if (hres == HOK) { 908 if (hres == HOK)
905 luaV_finishfastset(L, t, s2v(L->top.p - 1)); 909 luaV_finishfastset(L, t, s2v(L->top.p - 1));
906 }
907 else { 910 else {
908 TValue temp; 911 TValue temp;
909 setivalue(&temp, n); 912 setivalue(&temp, n);
diff --git a/ltable.c b/ltable.c
index d3e90696..21a54f81 100644
--- a/ltable.c
+++ b/ltable.c
@@ -408,21 +408,22 @@ static void freehash (lua_State *L, Table *t) {
408** not the real size of the array, the key still can be in the array 408** not the real size of the array, the key still can be in the array
409** part. In this case, do the "Xmilia trick" to check whether 'key-1' 409** part. In this case, do the "Xmilia trick" to check whether 'key-1'
410** is smaller than the real size. 410** is smaller than the real size.
411** The trick works as follow: let 'p' be an integer such that 411** The trick works as follow: let 'p' be the integer such that
412** '2^(p+1) >= alimit > 2^p', or '2^(p+1) > alimit-1 >= 2^p'. 412** '2^(p+1) >= alimit > 2^p', or '2^(p+1) > alimit-1 >= 2^p'. That is,
413** That is, 2^(p+1) is the real size of the array, and 'p' is the highest 413** 'p' is the highest 1-bit in 'alimit-1', and 2^(p+1) is the real size
414** bit on in 'alimit-1'. What we have to check becomes 'key-1 < 2^(p+1)'. 414** of the array. What we have to check becomes 'key-1 < 2^(p+1)'. We
415** We compute '(key-1) & ~(alimit-1)', which we call 'res'; it will 415** compute '(key-1) & ~(alimit-1)', which we call 'res'; it will have
416** have the 'p' bit cleared. If the key is outside the array, that is, 416** the 'p' bit cleared. (It may also clear other bits smaller than 'p',
417** 'key-1 >= 2^(p+1)', then 'res' will have some 1-bit higher than 'p', 417** but no bit higher than 'p'.) If the key is outside the array, that
418** therefore it will be larger or equal to 'alimit', and the check 418** is, 'key-1 >= 2^(p+1)', then 'res' will have some 1-bit higher than
419** 'p', therefore it will be larger or equal to 'alimit', and the check
419** will fail. If 'key-1 < 2^(p+1)', then 'res' has no 1-bit higher than 420** will fail. If 'key-1 < 2^(p+1)', then 'res' has no 1-bit higher than
420** 'p', and as the bit 'p' itself was cleared, 'res' will be smaller 421** 'p', and as the bit 'p' itself was cleared, 'res' will be smaller
421** than 2^p, therefore smaller than 'alimit', and the check succeeds. 422** than 2^p, therefore smaller than 'alimit', and the check succeeds.
422** As special cases, when 'alimit' is 0 the condition is trivially false, 423** As special cases, when 'alimit' is 0 the condition is trivially false,
423** and when 'alimit' is 1 the condition simplifies to 'key-1 < alimit'. 424** and when 'alimit' is 1 the condition simplifies to 'key-1 < alimit'.
424** If key is 0 or negative, 'res' will have its higher bit on, so that 425** If key is 0 or negative, 'res' will have its higher bit on, so that
425** if cannot be smaller than alimit. 426** it cannot be smaller than 'alimit'.
426*/ 427*/
427static int keyinarray (Table *t, lua_Integer key) { 428static int keyinarray (Table *t, lua_Integer key) {
428 lua_Unsigned alimit = t->alimit; 429 lua_Unsigned alimit = t->alimit;
@@ -788,11 +789,11 @@ static Node *getfreepos (Table *t) {
788 789
789 790
790/* 791/*
791** inserts a new key into a hash table; first, check whether key's main 792** Inserts a new key into a hash table; first, check whether key's main
792** position is free. If not, check whether colliding node is in its main 793** position is free. If not, check whether colliding node is in its main
793** position or not: if it is not, move colliding node to an empty place and 794** position or not: if it is not, move colliding node to an empty place
794** put new key in its main position; otherwise (colliding node is in its main 795** and put new key in its main position; otherwise (colliding node is in
795** position), new key goes to an empty position. 796** its main position), new key goes to an empty position.
796*/ 797*/
797static void luaH_newkey (lua_State *L, Table *t, const TValue *key, 798static void luaH_newkey (lua_State *L, Table *t, const TValue *key,
798 TValue *value) { 799 TValue *value) {
@@ -987,6 +988,16 @@ static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
987} 988}
988 989
989 990
991static int rawfinishnodeset (const TValue *slot, TValue *val) {
992 if (isabstkey(slot))
993 return 0; /* no slot with that key */
994 else {
995 setobj(((lua_State*)NULL), cast(TValue*, slot), val);
996 return 1; /* success */
997 }
998}
999
1000
990int luaH_psetint (Table *t, lua_Integer key, TValue *val) { 1001int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
991 if (keyinarray(t, key)) { 1002 if (keyinarray(t, key)) {
992 lu_byte *tag = getArrTag(t, key - 1); 1003 lu_byte *tag = getArrTag(t, key - 1);
@@ -1063,12 +1074,20 @@ void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
1063} 1074}
1064 1075
1065 1076
1077/*
1078** Ditto for a GC barrier. (No need to invalidate the TM cache, as
1079** integers cannot be keys to metamethods.)
1080*/
1066void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 1081void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
1067 int hres = luaH_psetint(t, key, value); 1082 if (keyinarray(t, key))
1068 if (hres != HOK) { 1083 obj2arr(t, key, value);
1069 TValue k; 1084 else {
1070 setivalue(&k, key); 1085 int ok = rawfinishnodeset(getintfromhash(t, key), value);
1071 luaH_finishset(L, t, &k, value, hres); 1086 if (!ok) {
1087 TValue k;
1088 setivalue(&k, key);
1089 luaH_newkey(L, t, &k, value);
1090 }
1072 } 1091 }
1073} 1092}
1074 1093
diff --git a/ltable.h b/ltable.h
index 5581efb1..8b0340b5 100644
--- a/ltable.h
+++ b/ltable.h
@@ -45,6 +45,25 @@
45#define nodefromval(v) cast(Node *, (v)) 45#define nodefromval(v) cast(Node *, (v))
46 46
47 47
48
49#define luaH_fastgeti(t,k,res,hres) \
50 { Table *h = t; lua_Unsigned u = l_castS2U(k); \
51 if ((u - 1u < h->alimit)) { \
52 int tag = *getArrTag(h,(u)-1u); \
53 if (tagisempty(tag)) hres = HNOTFOUND; \
54 else { farr2val(h, u, tag, res); hres = HOK; }} \
55 else { hres = luaH_getint(h, u, res); }}
56
57
58#define luaH_fastseti(t,k,val,hres) \
59 { Table *h = t; lua_Unsigned u = l_castS2U(k); \
60 if ((u - 1u < h->alimit)) { \
61 lu_byte *tag = getArrTag(h,(u)-1u); \
62 if (tagisempty(*tag)) hres = ~cast_int(u); \
63 else { fval2arr(h, u, tag, val); hres = HOK; }} \
64 else { hres = luaH_psetint(h, u, val); }}
65
66
48/* results from get/pset */ 67/* results from get/pset */
49#define HOK 0 68#define HOK 0
50#define HNOTFOUND 1 69#define HNOTFOUND 1
diff --git a/lvm.h b/lvm.h
index c74c81f8..54ee5dd7 100644
--- a/lvm.h
+++ b/lvm.h
@@ -78,35 +78,25 @@ typedef enum {
78/* 78/*
79** fast track for 'gettable' 79** fast track for 'gettable'
80*/ 80*/
81#define luaV_fastget(t,k,res,f, aux) \ 81#define luaV_fastget(t,k,res,f, hres) \
82 (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res))) 82 (hres = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res)))
83 83
84 84
85/* 85/*
86** Special case of 'luaV_fastget' for integers, inlining the fast case 86** Special case of 'luaV_fastget' for integers, inlining the fast case
87** of 'luaH_getint'. 87** of 'luaH_getint'.
88*/ 88*/
89#define luaV_fastgeti(t,k,res,aux) \ 89#define luaV_fastgeti(t,k,res,hres) \
90 if (!ttistable(t)) aux = HNOTATABLE; \ 90 if (!ttistable(t)) hres = HNOTATABLE; \
91 else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \ 91 else { luaH_fastgeti(hvalue(t), k, res, hres); }
92 if ((u - 1u < h->alimit)) { \ 92
93 int tag = *getArrTag(h,(u)-1u); \ 93
94 if (tagisempty(tag)) aux = HNOTFOUND; \ 94#define luaV_fastset(t,k,val,hres,f) \
95 else { farr2val(h, u, tag, res); aux = HOK; }} \ 95 (hres = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val)))
96 else { aux = luaH_getint(h, u, res); }} 96
97 97#define luaV_fastseti(t,k,val,hres) \
98 98 if (!ttistable(t)) hres = HNOTATABLE; \
99#define luaV_fastset(t,k,val,aux,f) \ 99 else { luaH_fastseti(hvalue(t), k, val, hres); }
100 (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val)))
101
102#define luaV_fastseti(t,k,val,aux) \
103 if (!ttistable(t)) aux = HNOTATABLE; \
104 else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \
105 if ((u - 1u < h->alimit)) { \
106 lu_byte *tag = getArrTag(h,(u)-1u); \
107 if (tagisempty(*tag)) aux = ~cast_int(u); \
108 else { fval2arr(h, u, tag, val); aux = HOK; }} \
109 else { aux = luaH_psetint(h, u, val); }}
110 100
111 101
112/* 102/*