aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c70
-rw-r--r--lcode.c8
-rw-r--r--llex.c10
-rw-r--r--ltable.c102
-rw-r--r--ltable.h37
-rw-r--r--ltm.c11
-rw-r--r--lvm.c112
-rw-r--r--lvm.h49
8 files changed, 189 insertions, 210 deletions
diff --git a/lapi.c b/lapi.c
index 97a9f272..4a3ba724 100644
--- a/lapi.c
+++ b/lapi.c
@@ -637,16 +637,16 @@ LUA_API int lua_pushthread (lua_State *L) {
637 637
638 638
639l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { 639l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) {
640 int aux; 640 int hres;
641 TString *str = luaS_new(L, k); 641 TString *str = luaS_new(L, k);
642 luaV_fastget1(t, str, s2v(L->top.p), luaH_getstr1, aux); 642 luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, hres);
643 if (aux == HOK) { 643 if (hres == HOK) {
644 api_incr_top(L); 644 api_incr_top(L);
645 } 645 }
646 else { 646 else {
647 setsvalue2s(L, L->top.p, str); 647 setsvalue2s(L, L->top.p, str);
648 api_incr_top(L); 648 api_incr_top(L);
649 luaV_finishget1(L, t, s2v(L->top.p - 1), L->top.p - 1, aux); 649 luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, hres);
650 } 650 }
651 lua_unlock(L); 651 lua_unlock(L);
652 return ttype(s2v(L->top.p - 1)); 652 return ttype(s2v(L->top.p - 1));
@@ -672,13 +672,13 @@ LUA_API int lua_getglobal (lua_State *L, const char *name) {
672 672
673 673
674LUA_API int lua_gettable (lua_State *L, int idx) { 674LUA_API int lua_gettable (lua_State *L, int idx) {
675 int aux; 675 int hres;
676 TValue *t; 676 TValue *t;
677 lua_lock(L); 677 lua_lock(L);
678 t = index2value(L, idx); 678 t = index2value(L, idx);
679 luaV_fastget1(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get1, aux); 679 luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, hres);
680 if (aux != HOK) 680 if (hres != HOK)
681 luaV_finishget1(L, t, s2v(L->top.p - 1), L->top.p - 1, aux); 681 luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, hres);
682 lua_unlock(L); 682 lua_unlock(L);
683 return ttype(s2v(L->top.p - 1)); 683 return ttype(s2v(L->top.p - 1));
684} 684}
@@ -692,14 +692,14 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) {
692 692
693LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { 693LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
694 TValue *t; 694 TValue *t;
695 int aux; 695 int hres;
696 lua_lock(L); 696 lua_lock(L);
697 t = index2value(L, idx); 697 t = index2value(L, idx);
698 luaV_fastgeti1(t, n, s2v(L->top.p), aux); 698 luaV_fastgeti(t, n, s2v(L->top.p), hres);
699 if (aux != HOK) { 699 if (hres != HOK) {
700 TValue key; 700 TValue key;
701 setivalue(&key, n); 701 setivalue(&key, n);
702 luaV_finishget1(L, t, &key, L->top.p, aux); 702 luaV_finishget(L, t, &key, L->top.p, hres);
703 } 703 }
704 api_incr_top(L); 704 api_incr_top(L);
705 lua_unlock(L); 705 lua_unlock(L);
@@ -707,11 +707,9 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) {
707} 707}
708 708
709 709
710l_sinline int finishrawget (lua_State *L, const TValue *val) { 710l_sinline int finishrawget (lua_State *L, int hres) {
711 if (isempty(val)) /* avoid copying empty items to the stack */ 711 if (hres != HOK) /* avoid copying empty items to the stack */
712 setnilvalue(s2v(L->top.p)); 712 setnilvalue(s2v(L->top.p));
713 else
714 setobj2s(L, L->top.p, val);
715 api_incr_top(L); 713 api_incr_top(L);
716 lua_unlock(L); 714 lua_unlock(L);
717 return ttype(s2v(L->top.p - 1)); 715 return ttype(s2v(L->top.p - 1));
@@ -727,13 +725,13 @@ static Table *gettable (lua_State *L, int idx) {
727 725
728LUA_API int lua_rawget (lua_State *L, int idx) { 726LUA_API int lua_rawget (lua_State *L, int idx) {
729 Table *t; 727 Table *t;
730 const TValue *val; 728 int hres;
731 lua_lock(L); 729 lua_lock(L);
732 api_checknelems(L, 1); 730 api_checknelems(L, 1);
733 t = gettable(L, idx); 731 t = gettable(L, idx);
734 val = luaH_get(t, s2v(L->top.p - 1)); 732 hres = luaH_get(t, s2v(L->top.p - 1), s2v(L->top.p - 1));
735 L->top.p--; /* remove key */ 733 L->top.p--; /* remove key */
736 return finishrawget(L, val); 734 return finishrawget(L, hres);
737} 735}
738 736
739 737
@@ -741,7 +739,7 @@ LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) {
741 Table *t; 739 Table *t;
742 lua_lock(L); 740 lua_lock(L);
743 t = gettable(L, idx); 741 t = gettable(L, idx);
744 return finishrawget(L, luaH_getint(t, n)); 742 return finishrawget(L, luaH_getint(t, n, s2v(L->top.p)));
745} 743}
746 744
747 745
@@ -751,7 +749,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) {
751 lua_lock(L); 749 lua_lock(L);
752 t = gettable(L, idx); 750 t = gettable(L, idx);
753 setpvalue(&k, cast_voidp(p)); 751 setpvalue(&k, cast_voidp(p));
754 return finishrawget(L, luaH_get(t, &k)); 752 return finishrawget(L, luaH_get(t, &k, s2v(L->top.p)));
755} 753}
756 754
757 755
@@ -823,18 +821,18 @@ LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) {
823** t[k] = value at the top of the stack (where 'k' is a string) 821** t[k] = value at the top of the stack (where 'k' is a string)
824*/ 822*/
825static void auxsetstr (lua_State *L, const TValue *t, const char *k) { 823static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
826 int aux; 824 int hres;
827 TString *str = luaS_new(L, k); 825 TString *str = luaS_new(L, k);
828 api_checknelems(L, 1); 826 api_checknelems(L, 1);
829 luaV_fastset1(t, str, s2v(L->top.p - 1), aux, luaH_setstr1); 827 luaV_fastset(t, str, s2v(L->top.p - 1), hres, luaH_psetstr);
830 if (aux == HOK) { 828 if (hres == HOK) {
831 luaV_finishfastset1(L, t, s2v(L->top.p - 1)); 829 luaV_finishfastset(L, t, s2v(L->top.p - 1));
832 L->top.p--; /* pop value */ 830 L->top.p--; /* pop value */
833 } 831 }
834 else { 832 else {
835 setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */ 833 setsvalue2s(L, L->top.p, str); /* push 'str' (to make it a TValue) */
836 api_incr_top(L); 834 api_incr_top(L);
837 luaV_finishset1(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), aux); 835 luaV_finishset(L, t, s2v(L->top.p - 1), s2v(L->top.p - 2), hres);
838 L->top.p -= 2; /* pop value and key */ 836 L->top.p -= 2; /* pop value and key */
839 } 837 }
840 lua_unlock(L); /* lock done by caller */ 838 lua_unlock(L); /* lock done by caller */
@@ -851,16 +849,16 @@ LUA_API void lua_setglobal (lua_State *L, const char *name) {
851 849
852LUA_API void lua_settable (lua_State *L, int idx) { 850LUA_API void lua_settable (lua_State *L, int idx) {
853 TValue *t; 851 TValue *t;
854 int aux; 852 int hres;
855 lua_lock(L); 853 lua_lock(L);
856 api_checknelems(L, 2); 854 api_checknelems(L, 2);
857 t = index2value(L, idx); 855 t = index2value(L, idx);
858 luaV_fastset1(t, s2v(L->top.p - 2), s2v(L->top.p - 1), aux, luaH_set1); 856 luaV_fastset(t, s2v(L->top.p - 2), s2v(L->top.p - 1), hres, luaH_pset);
859 if (aux == HOK) { 857 if (hres == HOK) {
860 luaV_finishfastset1(L, t, s2v(L->top.p - 1)); 858 luaV_finishfastset(L, t, s2v(L->top.p - 1));
861 } 859 }
862 else 860 else
863 luaV_finishset1(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), aux); 861 luaV_finishset(L, t, s2v(L->top.p - 2), s2v(L->top.p - 1), hres);
864 L->top.p -= 2; /* pop index and value */ 862 L->top.p -= 2; /* pop index and value */
865 lua_unlock(L); 863 lua_unlock(L);
866} 864}
@@ -874,18 +872,18 @@ LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
874 872
875LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { 873LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
876 TValue *t; 874 TValue *t;
877 int aux; 875 int hres;
878 lua_lock(L); 876 lua_lock(L);
879 api_checknelems(L, 1); 877 api_checknelems(L, 1);
880 t = index2value(L, idx); 878 t = index2value(L, idx);
881 luaV_fastseti1(t, n, s2v(L->top.p - 1), aux); 879 luaV_fastseti(t, n, s2v(L->top.p - 1), hres);
882 if (aux == HOK) { 880 if (hres == HOK) {
883 luaV_finishfastset1(L, t, s2v(L->top.p - 1)); 881 luaV_finishfastset(L, t, s2v(L->top.p - 1));
884 } 882 }
885 else { 883 else {
886 TValue temp; 884 TValue temp;
887 setivalue(&temp, n); 885 setivalue(&temp, n);
888 luaV_finishset1(L, t, &temp, s2v(L->top.p - 1), aux); 886 luaV_finishset(L, t, &temp, s2v(L->top.p - 1), hres);
889 } 887 }
890 L->top.p--; /* pop value */ 888 L->top.p--; /* pop value */
891 lua_unlock(L); 889 lua_unlock(L);
diff --git a/lcode.c b/lcode.c
index 1a371ca9..25623df7 100644
--- a/lcode.c
+++ b/lcode.c
@@ -544,10 +544,10 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
544 TValue val; 544 TValue val;
545 lua_State *L = fs->ls->L; 545 lua_State *L = fs->ls->L;
546 Proto *f = fs->f; 546 Proto *f = fs->f;
547 const TValue *idx = luaH_get(fs->ls->h, key); /* query scanner table */ 547 int aux = luaH_get(fs->ls->h, key, &val); /* query scanner table */
548 int k, oldsize; 548 int k, oldsize;
549 if (ttisinteger(idx)) { /* is there an index there? */ 549 if (aux == HOK && ttisinteger(&val)) { /* is there an index there? */
550 k = cast_int(ivalue(idx)); 550 k = cast_int(ivalue(&val));
551 /* correct value? (warning: must distinguish floats from integers!) */ 551 /* correct value? (warning: must distinguish floats from integers!) */
552 if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && 552 if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) &&
553 luaV_rawequalobj(&f->k[k], v)) 553 luaV_rawequalobj(&f->k[k], v))
@@ -559,7 +559,7 @@ static int addk (FuncState *fs, TValue *key, TValue *v) {
559 /* numerical value does not need GC barrier; 559 /* numerical value does not need GC barrier;
560 table has no metatable, so it does not need to invalidate cache */ 560 table has no metatable, so it does not need to invalidate cache */
561 setivalue(&val, k); 561 setivalue(&val, k);
562 luaH_finishset(L, fs->ls->h, key, idx, &val); 562 luaH_set(L, fs->ls->h, key, &val);
563 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants"); 563 luaM_growvector(L, f->k, k, f->sizek, TValue, MAXARG_Ax, "constants");
564 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]); 564 while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
565 setobj(L, &f->k[k], v); 565 setobj(L, &f->k[k], v);
diff --git a/llex.c b/llex.c
index 5fc39a5c..9f20d3c8 100644
--- a/llex.c
+++ b/llex.c
@@ -134,13 +134,13 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) {
134TString *luaX_newstring (LexState *ls, const char *str, size_t l) { 134TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
135 lua_State *L = ls->L; 135 lua_State *L = ls->L;
136 TString *ts = luaS_newlstr(L, str, l); /* create new string */ 136 TString *ts = luaS_newlstr(L, str, l); /* create new string */
137 const TValue *o = luaH_getstr(ls->h, ts); 137 TString *oldts = luaH_getstrkey(ls->h, ts);
138 if (!ttisnil(o)) /* string already present? */ 138 if (oldts != NULL) /* string already present? */
139 ts = keystrval(nodefromval(o)); /* get saved copy */ 139 return oldts; /* use it */
140 else { /* not in use yet */ 140 else { /* create a new entry */
141 TValue *stv = s2v(L->top.p++); /* reserve stack space for string */ 141 TValue *stv = s2v(L->top.p++); /* reserve stack space for string */
142 setsvalue(L, stv, ts); /* temporarily anchor the string */ 142 setsvalue(L, stv, ts); /* temporarily anchor the string */
143 luaH_finishset(L, ls->h, stv, o, stv); /* t[string] = string */ 143 luaH_set(L, ls->h, stv, stv); /* t[string] = string */
144 /* table is not a metatable, so it does not need to invalidate cache */ 144 /* table is not a metatable, so it does not need to invalidate cache */
145 luaC_checkGC(L); 145 luaC_checkGC(L);
146 L->top.p--; /* remove string from stack */ 146 L->top.p--; /* remove string from stack */
diff --git a/ltable.c b/ltable.c
index 902f05a7..3f95ab0c 100644
--- a/ltable.c
+++ b/ltable.c
@@ -756,7 +756,7 @@ static const TValue *getintfromhash (Table *t, lua_Integer key) {
756** one more than the limit (so that it can be incremented without 756** one more than the limit (so that it can be incremented without
757** changing the real size of the array). 757** changing the real size of the array).
758*/ 758*/
759const TValue *luaH_getint (Table *t, lua_Integer key) { 759static const TValue *Hgetint (Table *t, lua_Integer key) {
760 const TValue *slot = getintfromarray(t, key); 760 const TValue *slot = getintfromarray(t, key);
761 if (slot != NULL) 761 if (slot != NULL)
762 return slot; 762 return slot;
@@ -775,15 +775,15 @@ static int finishnodeget (const TValue *val, TValue *res) {
775} 775}
776 776
777 777
778int luaH_getint1 (Table *t, lua_Integer key, TValue *res) { 778int luaH_getint (Table *t, lua_Integer key, TValue *res) {
779 return finishnodeget(luaH_getint(t, key), res); 779 return finishnodeget(Hgetint(t, key), res);
780} 780}
781 781
782 782
783/* 783/*
784** search function for short strings 784** search function for short strings
785*/ 785*/
786const TValue *luaH_getshortstr (Table *t, TString *key) { 786const TValue *luaH_Hgetshortstr (Table *t, TString *key) {
787 Node *n = hashstr(t, key); 787 Node *n = hashstr(t, key);
788 lua_assert(key->tt == LUA_VSHRSTR); 788 lua_assert(key->tt == LUA_VSHRSTR);
789 for (;;) { /* check whether 'key' is somewhere in the chain */ 789 for (;;) { /* check whether 'key' is somewhere in the chain */
@@ -799,14 +799,14 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
799} 799}
800 800
801 801
802int luaH_getshortstr1 (Table *t, TString *key, TValue *res) { 802int luaH_getshortstr (Table *t, TString *key, TValue *res) {
803 return finishnodeget(luaH_getshortstr(t, key), res); 803 return finishnodeget(luaH_Hgetshortstr(t, key), res);
804} 804}
805 805
806 806
807const TValue *luaH_getstr (Table *t, TString *key) { 807static const TValue *Hgetstr (Table *t, TString *key) {
808 if (key->tt == LUA_VSHRSTR) 808 if (key->tt == LUA_VSHRSTR)
809 return luaH_getshortstr(t, key); 809 return luaH_Hgetshortstr(t, key);
810 else { /* for long strings, use generic case */ 810 else { /* for long strings, use generic case */
811 TValue ko; 811 TValue ko;
812 setsvalue(cast(lua_State *, NULL), &ko, key); 812 setsvalue(cast(lua_State *, NULL), &ko, key);
@@ -815,23 +815,32 @@ const TValue *luaH_getstr (Table *t, TString *key) {
815} 815}
816 816
817 817
818int luaH_getstr1 (Table *t, TString *key, TValue *res) { 818int luaH_getstr (Table *t, TString *key, TValue *res) {
819 return finishnodeget(luaH_getstr(t, key), res); 819 return finishnodeget(Hgetstr(t, key), res);
820}
821
822
823TString *luaH_getstrkey (Table *t, TString *key) {
824 const TValue *o = Hgetstr(t, key);
825 if (!isabstkey(o)) /* string already present? */
826 return keystrval(nodefromval(o)); /* get saved copy */
827 else
828 return NULL;
820} 829}
821 830
822 831
823/* 832/*
824** main search function 833** main search function
825*/ 834*/
826const TValue *luaH_get (Table *t, const TValue *key) { 835static const TValue *Hget (Table *t, const TValue *key) {
827 switch (ttypetag(key)) { 836 switch (ttypetag(key)) {
828 case LUA_VSHRSTR: return luaH_getshortstr(t, tsvalue(key)); 837 case LUA_VSHRSTR: return luaH_Hgetshortstr(t, tsvalue(key));
829 case LUA_VNUMINT: return luaH_getint(t, ivalue(key)); 838 case LUA_VNUMINT: return Hgetint(t, ivalue(key));
830 case LUA_VNIL: return &absentkey; 839 case LUA_VNIL: return &absentkey;
831 case LUA_VNUMFLT: { 840 case LUA_VNUMFLT: {
832 lua_Integer k; 841 lua_Integer k;
833 if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ 842 if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
834 return luaH_getint(t, k); /* use specialized version */ 843 return Hgetint(t, k); /* use specialized version */
835 /* else... */ 844 /* else... */
836 } /* FALLTHROUGH */ 845 } /* FALLTHROUGH */
837 default: 846 default:
@@ -840,8 +849,8 @@ const TValue *luaH_get (Table *t, const TValue *key) {
840} 849}
841 850
842 851
843int luaH_get1 (Table *t, const TValue *key, TValue *res) { 852int luaH_get (Table *t, const TValue *key, TValue *res) {
844 return finishnodeget(luaH_get(t, key), res); 853 return finishnodeget(Hget(t, key), res);
845} 854}
846 855
847 856
@@ -856,7 +865,7 @@ static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
856} 865}
857 866
858 867
859int luaH_setint1 (Table *t, lua_Integer key, TValue *val) { 868int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
860 const TValue *slot = getintfromarray(t, key); 869 const TValue *slot = getintfromarray(t, key);
861 if (slot != NULL) { 870 if (slot != NULL) {
862 if (!ttisnil(slot)) { 871 if (!ttisnil(slot)) {
@@ -871,25 +880,25 @@ int luaH_setint1 (Table *t, lua_Integer key, TValue *val) {
871} 880}
872 881
873 882
874int luaH_setshortstr1 (Table *t, TString *key, TValue *val) { 883int luaH_psetshortstr (Table *t, TString *key, TValue *val) {
875 return finishnodeset(t, luaH_getshortstr(t, key), val); 884 return finishnodeset(t, luaH_Hgetshortstr(t, key), val);
876} 885}
877 886
878 887
879int luaH_setstr1 (Table *t, TString *key, TValue *val) { 888int luaH_psetstr (Table *t, TString *key, TValue *val) {
880 return finishnodeset(t, luaH_getstr(t, key), val); 889 return finishnodeset(t, Hgetstr(t, key), val);
881} 890}
882 891
883 892
884int luaH_set1 (Table *t, const TValue *key, TValue *val) { 893int luaH_pset (Table *t, const TValue *key, TValue *val) {
885 switch (ttypetag(key)) { 894 switch (ttypetag(key)) {
886 case LUA_VSHRSTR: return luaH_setshortstr1(t, tsvalue(key), val); 895 case LUA_VSHRSTR: return luaH_psetshortstr(t, tsvalue(key), val);
887 case LUA_VNUMINT: return luaH_setint1(t, ivalue(key), val); 896 case LUA_VNUMINT: return luaH_psetint(t, ivalue(key), val);
888 case LUA_VNIL: return HNOTFOUND; 897 case LUA_VNIL: return HNOTFOUND;
889 case LUA_VNUMFLT: { 898 case LUA_VNUMFLT: {
890 lua_Integer k; 899 lua_Integer k;
891 if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ 900 if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */
892 return luaH_setint1(t, k, val); /* use specialized version */ 901 return luaH_psetint(t, k, val); /* use specialized version */
893 /* else... */ 902 /* else... */
894 } /* FALLTHROUGH */ 903 } /* FALLTHROUGH */
895 default: 904 default:
@@ -903,26 +912,20 @@ int luaH_set1 (Table *t, const TValue *key, TValue *val) {
903** Beware: when using this function you probably need to check a GC 912** Beware: when using this function you probably need to check a GC
904** barrier and invalidate the TM cache. 913** barrier and invalidate the TM cache.
905*/ 914*/
906void luaH_finishset (lua_State *L, Table *t, const TValue *key,
907 const TValue *slot, TValue *value) {
908 if (isabstkey(slot))
909 luaH_newkey(L, t, key, value);
910 else
911 setobj2t(L, cast(TValue *, slot), value);
912}
913 915
914 916
915void luaH_finishset1 (lua_State *L, Table *t, const TValue *key, 917void luaH_finishset (lua_State *L, Table *t, const TValue *key,
916 TValue *value, int aux) { 918 TValue *value, int hres) {
917 if (aux == HNOTFOUND) { 919 lua_assert(hres != HOK);
920 if (hres == HNOTFOUND) {
918 luaH_newkey(L, t, key, value); 921 luaH_newkey(L, t, key, value);
919 } 922 }
920 else if (aux > 0) { /* regular Node? */ 923 else if (hres > 0) { /* regular Node? */
921 setobj2t(L, gval(gnode(t, aux - HFIRSTNODE)), value); 924 setobj2t(L, gval(gnode(t, hres - HFIRSTNODE)), value);
922 } 925 }
923 else { /* array entry */ 926 else { /* array entry */
924 aux = ~aux; /* real index */ 927 hres = ~hres; /* real index */
925 val2arr(t, aux, getArrTag(t, aux), value); 928 val2arr(t, hres, getArrTag(t, hres), value);
926 } 929 }
927} 930}
928 931
@@ -932,20 +935,19 @@ void luaH_finishset1 (lua_State *L, Table *t, const TValue *key,
932** barrier and invalidate the TM cache. 935** barrier and invalidate the TM cache.
933*/ 936*/
934void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { 937void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
935 const TValue *slot = luaH_get(t, key); 938 int hres = luaH_pset(t, key, value);
936 luaH_finishset(L, t, key, slot, value); 939 if (hres != HOK)
940 luaH_finishset(L, t, key, value, hres);
937} 941}
938 942
939 943
940void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 944void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
941 const TValue *p = luaH_getint(t, key); 945 int hres = luaH_psetint(t, key, value);
942 if (isabstkey(p)) { 946 if (hres != HOK) {
943 TValue k; 947 TValue k;
944 setivalue(&k, key); 948 setivalue(&k, key);
945 luaH_newkey(L, t, &k, value); 949 luaH_finishset(L, t, &k, value, hres);
946 } 950 }
947 else
948 setobj2t(L, cast(TValue *, p), value);
949} 951}
950 952
951 953
@@ -971,16 +973,16 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
971 j *= 2; 973 j *= 2;
972 else { 974 else {
973 j = LUA_MAXINTEGER; 975 j = LUA_MAXINTEGER;
974 if (isempty(luaH_getint(t, j))) /* t[j] not present? */ 976 if (isempty(Hgetint(t, j))) /* t[j] not present? */
975 break; /* 'j' now is an absent index */ 977 break; /* 'j' now is an absent index */
976 else /* weird case */ 978 else /* weird case */
977 return j; /* well, max integer is a boundary... */ 979 return j; /* well, max integer is a boundary... */
978 } 980 }
979 } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */ 981 } while (!isempty(Hgetint(t, j))); /* repeat until an absent t[j] */
980 /* i < j && t[i] present && t[j] absent */ 982 /* i < j && t[i] present && t[j] absent */
981 while (j - i > 1u) { /* do a binary search between them */ 983 while (j - i > 1u) { /* do a binary search between them */
982 lua_Unsigned m = (i + j) / 2; 984 lua_Unsigned m = (i + j) / 2;
983 if (isempty(luaH_getint(t, m))) j = m; 985 if (isempty(Hgetint(t, m))) j = m;
984 else i = m; 986 else i = m;
985 } 987 }
986 return i; 988 return i;
@@ -1071,7 +1073,7 @@ lua_Unsigned luaH_getn (Table *t) {
1071 /* (3) 'limit' is the last element and either is zero or present in table */ 1073 /* (3) 'limit' is the last element and either is zero or present in table */
1072 lua_assert(limit == luaH_realasize(t) && 1074 lua_assert(limit == luaH_realasize(t) &&
1073 (limit == 0 || !isempty(&t->array[limit - 1]))); 1075 (limit == 0 || !isempty(&t->array[limit - 1])));
1074 if (isdummy(t) || isempty(luaH_getint(t, cast(lua_Integer, limit + 1)))) 1076 if (isdummy(t) || isempty(Hgetint(t, cast(lua_Integer, limit + 1))))
1075 return limit; /* 'limit + 1' is absent */ 1077 return limit; /* 'limit + 1' is absent */
1076 else /* 'limit + 1' is also present */ 1078 else /* 'limit + 1' is also present */
1077 return hash_search(t, limit); 1079 return hash_search(t, limit);
diff --git a/ltable.h b/ltable.h
index b9bb416a..5ec7b447 100644
--- a/ltable.h
+++ b/ltable.h
@@ -35,12 +35,22 @@
35#define nodefromval(v) cast(Node *, (v)) 35#define nodefromval(v) cast(Node *, (v))
36 36
37 37
38/* results from get/set */ 38/* results from get/pset */
39#define HOK 0 39#define HOK 0
40#define HNOTFOUND 1 40#define HNOTFOUND 1
41#define HNOTATABLE 2 41#define HNOTATABLE 2
42#define HFIRSTNODE 3 42#define HFIRSTNODE 3
43 43
44/*
45** Besides these values, pset (pre-set) operations may also return an
46** encoding of where the value should go (usually called 'hres'). That
47** means that there is a slot with that key but with no value. (pset
48** cannot set that value because there might be a metamethod.) If the
49** slot is in the hash part, the encoding is (HFIRSTNODE + hash index);
50** if the slot is in the array part, the encoding is (~array index).
51*/
52
53
44 54
45/* fast access to components of array values */ 55/* fast access to components of array values */
46#define getArrTag(t,k) (&(t)->array[k - 1].tt_) 56#define getArrTag(t,k) (&(t)->array[k - 1].tt_)
@@ -55,29 +65,26 @@
55 (*tag = (val)->tt_, *getArrVal(h,k) = (val)->value_) 65 (*tag = (val)->tt_, *getArrVal(h,k) = (val)->value_)
56 66
57 67
58LUAI_FUNC int luaH_getshortstr1 (Table *t, TString *key, TValue *res); 68LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res);
59LUAI_FUNC int luaH_getstr1 (Table *t, TString *key, TValue *res); 69LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res);
60LUAI_FUNC int luaH_get1 (Table *t, const TValue *key, TValue *res); 70LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res);
61LUAI_FUNC int luaH_getint1 (Table *t, lua_Integer key, TValue *res); 71LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res);
72
73LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key);
62 74
63LUAI_FUNC int luaH_setint1 (Table *t, lua_Integer key, TValue *val); 75LUAI_FUNC int luaH_psetint (Table *t, lua_Integer key, TValue *val);
64LUAI_FUNC int luaH_setshortstr1 (Table *t, TString *key, TValue *val); 76LUAI_FUNC int luaH_psetshortstr (Table *t, TString *key, TValue *val);
65LUAI_FUNC int luaH_setstr1 (Table *t, TString *key, TValue *val); 77LUAI_FUNC int luaH_psetstr (Table *t, TString *key, TValue *val);
66LUAI_FUNC int luaH_set1 (Table *t, const TValue *key, TValue *val); 78LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val);
67 79
68LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
69LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, 80LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
70 TValue *value); 81 TValue *value);
71LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); 82LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key);
72LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
73LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
74LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, 83LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key,
75 TValue *value); 84 TValue *value);
76LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, 85LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key,
77 TValue *value); 86 TValue *value);
78LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, 87LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key,
79 const TValue *slot, TValue *value);
80LUAI_FUNC void luaH_finishset1 (lua_State *L, Table *t, const TValue *key,
81 TValue *value, int aux); 88 TValue *value, int aux);
82LUAI_FUNC Table *luaH_new (lua_State *L); 89LUAI_FUNC Table *luaH_new (lua_State *L);
83LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 90LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
diff --git a/ltm.c b/ltm.c
index 07a06081..fce6245c 100644
--- a/ltm.c
+++ b/ltm.c
@@ -58,7 +58,7 @@ void luaT_init (lua_State *L) {
58** tag methods 58** tag methods
59*/ 59*/
60const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { 60const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
61 const TValue *tm = luaH_getshortstr(events, ename); 61 const TValue *tm = luaH_Hgetshortstr(events, ename);
62 lua_assert(event <= TM_EQ); 62 lua_assert(event <= TM_EQ);
63 if (notm(tm)) { /* no tag method? */ 63 if (notm(tm)) { /* no tag method? */
64 events->flags |= cast_byte(1u<<event); /* cache this fact */ 64 events->flags |= cast_byte(1u<<event); /* cache this fact */
@@ -80,7 +80,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
80 default: 80 default:
81 mt = G(L)->mt[ttype(o)]; 81 mt = G(L)->mt[ttype(o)];
82 } 82 }
83 return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue); 83 return (mt ? luaH_Hgetshortstr(mt, G(L)->tmname[event]) : &G(L)->nilvalue);
84} 84}
85 85
86 86
@@ -92,9 +92,10 @@ const char *luaT_objtypename (lua_State *L, const TValue *o) {
92 Table *mt; 92 Table *mt;
93 if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) || 93 if ((ttistable(o) && (mt = hvalue(o)->metatable) != NULL) ||
94 (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) { 94 (ttisfulluserdata(o) && (mt = uvalue(o)->metatable) != NULL)) {
95 const TValue *name = luaH_getshortstr(mt, luaS_new(L, "__name")); 95 TValue name;
96 if (ttisstring(name)) /* is '__name' a string? */ 96 int hres = luaH_getshortstr(mt, luaS_new(L, "__name"), &name);
97 return getstr(tsvalue(name)); /* use it as type name */ 97 if (hres == HOK && ttisstring(&name)) /* is '__name' a string? */
98 return getstr(tsvalue(&name)); /* use it as type name */
98 } 99 }
99 return ttypename(ttype(o)); /* else use standard type name */ 100 return ttypename(ttype(o)); /* else use standard type name */
100} 101}
diff --git a/lvm.c b/lvm.c
index f5934025..96413718 100644
--- a/lvm.c
+++ b/lvm.c
@@ -281,15 +281,13 @@ static int floatforloop (StkId ra) {
281 281
282/* 282/*
283** Finish the table access 'val = t[key]'. 283** Finish the table access 'val = t[key]'.
284** if 'slot' is NULL, 't' is not a table; otherwise, 'slot' points to
285** t[k] entry (which must be empty).
286*/ 284*/
287void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val, 285void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
288 int aux) { 286 int hres) {
289 int loop; /* counter to avoid infinite loops */ 287 int loop; /* counter to avoid infinite loops */
290 const TValue *tm; /* metamethod */ 288 const TValue *tm; /* metamethod */
291 for (loop = 0; loop < MAXTAGLOOP; loop++) { 289 for (loop = 0; loop < MAXTAGLOOP; loop++) {
292 if (aux == HNOTATABLE) { /* 't' is not a table? */ 290 if (hres == HNOTATABLE) { /* 't' is not a table? */
293 lua_assert(!ttistable(t)); 291 lua_assert(!ttistable(t));
294 tm = luaT_gettmbyobj(L, t, TM_INDEX); 292 tm = luaT_gettmbyobj(L, t, TM_INDEX);
295 if (l_unlikely(notm(tm))) 293 if (l_unlikely(notm(tm)))
@@ -309,8 +307,8 @@ void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val,
309 return; 307 return;
310 } 308 }
311 t = tm; /* else try to access 'tm[key]' */ 309 t = tm; /* else try to access 'tm[key]' */
312 luaV_fastget1(t, key, s2v(val), luaH_get1, aux); 310 luaV_fastget(t, key, s2v(val), luaH_get, hres);
313 if (aux == HOK) 311 if (hres == HOK)
314 return; /* done */ 312 return; /* done */
315 /* else repeat (tail call 'luaV_finishget') */ 313 /* else repeat (tail call 'luaV_finishget') */
316 } 314 }
@@ -320,21 +318,17 @@ void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val,
320 318
321/* 319/*
322** Finish a table assignment 't[key] = val'. 320** Finish a table assignment 't[key] = val'.
323** If 'slot' is NULL, 't' is not a table. Otherwise, 'slot' points
324** to the entry 't[key]', or to a value with an absent key if there
325** is no such entry. (The value at 'slot' must be empty, otherwise
326** 'luaV_fastget' would have done the job.)
327*/ 321*/
328void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key, 322void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
329 TValue *val, int aux) { 323 TValue *val, int hres) {
330 int loop; /* counter to avoid infinite loops */ 324 int loop; /* counter to avoid infinite loops */
331 for (loop = 0; loop < MAXTAGLOOP; loop++) { 325 for (loop = 0; loop < MAXTAGLOOP; loop++) {
332 const TValue *tm; /* '__newindex' metamethod */ 326 const TValue *tm; /* '__newindex' metamethod */
333 if (aux != HNOTATABLE) { /* is 't' a table? */ 327 if (hres != HNOTATABLE) { /* is 't' a table? */
334 Table *h = hvalue(t); /* save 't' table */ 328 Table *h = hvalue(t); /* save 't' table */
335 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */ 329 tm = fasttm(L, h->metatable, TM_NEWINDEX); /* get metamethod */
336 if (tm == NULL) { /* no metamethod? */ 330 if (tm == NULL) { /* no metamethod? */
337 luaH_finishset1(L, h, key, val, aux); /* set new value */ 331 luaH_finishset(L, h, key, val, hres); /* set new value */
338 invalidateTMcache(h); 332 invalidateTMcache(h);
339 luaC_barrierback(L, obj2gco(h), val); 333 luaC_barrierback(L, obj2gco(h), val);
340 return; 334 return;
@@ -352,8 +346,8 @@ void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key,
352 return; 346 return;
353 } 347 }
354 t = tm; /* else repeat assignment over 'tm' */ 348 t = tm; /* else repeat assignment over 'tm' */
355 luaV_fastset1(t, key, val, aux, luaH_set1); 349 luaV_fastset(t, key, val, hres, luaH_pset);
356 if (aux == HOK) 350 if (hres == HOK)
357 return; /* done */ 351 return; /* done */
358 /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */ 352 /* else 'return luaV_finishset(L, t, key, val, slot)' (loop) */
359 } 353 }
@@ -1249,36 +1243,36 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1249 TValue *upval = cl->upvals[GETARG_B(i)]->v.p; 1243 TValue *upval = cl->upvals[GETARG_B(i)]->v.p;
1250 TValue *rc = KC(i); 1244 TValue *rc = KC(i);
1251 TString *key = tsvalue(rc); /* key must be a string */ 1245 TString *key = tsvalue(rc); /* key must be a string */
1252 int aux; 1246 int hres;
1253 luaV_fastget1(upval, key, s2v(ra), luaH_getshortstr1, aux); 1247 luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres);
1254 if (aux != HOK) 1248 if (hres != HOK)
1255 Protect(luaV_finishget1(L, upval, rc, ra, aux)); 1249 Protect(luaV_finishget(L, upval, rc, ra, hres));
1256 vmbreak; 1250 vmbreak;
1257 } 1251 }
1258 vmcase(OP_GETTABLE) { 1252 vmcase(OP_GETTABLE) {
1259 StkId ra = RA(i); 1253 StkId ra = RA(i);
1260 TValue *rb = vRB(i); 1254 TValue *rb = vRB(i);
1261 TValue *rc = vRC(i); 1255 TValue *rc = vRC(i);
1262 int aux; 1256 int hres;
1263 if (ttisinteger(rc)) { /* fast track for integers? */ 1257 if (ttisinteger(rc)) { /* fast track for integers? */
1264 luaV_fastgeti1(rb, ivalue(rc), s2v(ra), aux); 1258 luaV_fastgeti(rb, ivalue(rc), s2v(ra), hres);
1265 } 1259 }
1266 else 1260 else
1267 luaV_fastget1(rb, rc, s2v(ra), luaH_get1, aux); 1261 luaV_fastget(rb, rc, s2v(ra), luaH_get, hres);
1268 if (aux != HOK) /* fast track for integers? */ 1262 if (hres != HOK) /* fast track for integers? */
1269 Protect(luaV_finishget1(L, rb, rc, ra, aux)); 1263 Protect(luaV_finishget(L, rb, rc, ra, hres));
1270 vmbreak; 1264 vmbreak;
1271 } 1265 }
1272 vmcase(OP_GETI) { 1266 vmcase(OP_GETI) {
1273 StkId ra = RA(i); 1267 StkId ra = RA(i);
1274 TValue *rb = vRB(i); 1268 TValue *rb = vRB(i);
1275 int c = GETARG_C(i); 1269 int c = GETARG_C(i);
1276 int aux; 1270 int hres;
1277 luaV_fastgeti1(rb, c, s2v(ra), aux); 1271 luaV_fastgeti(rb, c, s2v(ra), hres);
1278 if (aux != HOK) { 1272 if (hres != HOK) {
1279 TValue key; 1273 TValue key;
1280 setivalue(&key, c); 1274 setivalue(&key, c);
1281 Protect(luaV_finishget1(L, rb, &key, ra, aux)); 1275 Protect(luaV_finishget(L, rb, &key, ra, hres));
1282 } 1276 }
1283 vmbreak; 1277 vmbreak;
1284 } 1278 }
@@ -1287,68 +1281,68 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1287 TValue *rb = vRB(i); 1281 TValue *rb = vRB(i);
1288 TValue *rc = KC(i); 1282 TValue *rc = KC(i);
1289 TString *key = tsvalue(rc); /* key must be a string */ 1283 TString *key = tsvalue(rc); /* key must be a string */
1290 int aux; 1284 int hres;
1291 luaV_fastget1(rb, key, s2v(ra), luaH_getshortstr1, aux); 1285 luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres);
1292 if (aux != HOK) 1286 if (hres != HOK)
1293 Protect(luaV_finishget1(L, rb, rc, ra, aux)); 1287 Protect(luaV_finishget(L, rb, rc, ra, hres));
1294 vmbreak; 1288 vmbreak;
1295 } 1289 }
1296 vmcase(OP_SETTABUP) { 1290 vmcase(OP_SETTABUP) {
1297 int aux; 1291 int hres;
1298 TValue *upval = cl->upvals[GETARG_A(i)]->v.p; 1292 TValue *upval = cl->upvals[GETARG_A(i)]->v.p;
1299 TValue *rb = KB(i); 1293 TValue *rb = KB(i);
1300 TValue *rc = RKC(i); 1294 TValue *rc = RKC(i);
1301 TString *key = tsvalue(rb); /* key must be a string */ 1295 TString *key = tsvalue(rb); /* key must be a string */
1302 luaV_fastset1(upval, key, rc, aux, luaH_setshortstr1); 1296 luaV_fastset(upval, key, rc, hres, luaH_psetshortstr);
1303 if (aux == HOK) 1297 if (hres == HOK)
1304 luaV_finishfastset1(L, upval, rc); 1298 luaV_finishfastset(L, upval, rc);
1305 else 1299 else
1306 Protect(luaV_finishset1(L, upval, rb, rc, aux)); 1300 Protect(luaV_finishset(L, upval, rb, rc, hres));
1307 vmbreak; 1301 vmbreak;
1308 } 1302 }
1309 vmcase(OP_SETTABLE) { 1303 vmcase(OP_SETTABLE) {
1310 StkId ra = RA(i); 1304 StkId ra = RA(i);
1311 int aux; 1305 int hres;
1312 TValue *rb = vRB(i); /* key (table is in 'ra') */ 1306 TValue *rb = vRB(i); /* key (table is in 'ra') */
1313 TValue *rc = RKC(i); /* value */ 1307 TValue *rc = RKC(i); /* value */
1314 if (ttisinteger(rb)) { /* fast track for integers? */ 1308 if (ttisinteger(rb)) { /* fast track for integers? */
1315 luaV_fastseti1(s2v(ra), ivalue(rb), rc, aux); 1309 luaV_fastseti(s2v(ra), ivalue(rb), rc, hres);
1316 } 1310 }
1317 else { 1311 else {
1318 luaV_fastset1(s2v(ra), rb, rc, aux, luaH_set1); 1312 luaV_fastset(s2v(ra), rb, rc, hres, luaH_pset);
1319 } 1313 }
1320 if (aux == HOK) 1314 if (hres == HOK)
1321 luaV_finishfastset1(L, s2v(ra), rc); 1315 luaV_finishfastset(L, s2v(ra), rc);
1322 else 1316 else
1323 Protect(luaV_finishset1(L, s2v(ra), rb, rc, aux)); 1317 Protect(luaV_finishset(L, s2v(ra), rb, rc, hres));
1324 vmbreak; 1318 vmbreak;
1325 } 1319 }
1326 vmcase(OP_SETI) { 1320 vmcase(OP_SETI) {
1327 StkId ra = RA(i); 1321 StkId ra = RA(i);
1328 int aux; 1322 int hres;
1329 int b = GETARG_B(i); 1323 int b = GETARG_B(i);
1330 TValue *rc = RKC(i); 1324 TValue *rc = RKC(i);
1331 luaV_fastseti1(s2v(ra), b, rc, aux); 1325 luaV_fastseti(s2v(ra), b, rc, hres);
1332 if (aux == HOK) 1326 if (hres == HOK)
1333 luaV_finishfastset1(L, s2v(ra), rc); 1327 luaV_finishfastset(L, s2v(ra), rc);
1334 else { 1328 else {
1335 TValue key; 1329 TValue key;
1336 setivalue(&key, b); 1330 setivalue(&key, b);
1337 Protect(luaV_finishset1(L, s2v(ra), &key, rc, aux)); 1331 Protect(luaV_finishset(L, s2v(ra), &key, rc, hres));
1338 } 1332 }
1339 vmbreak; 1333 vmbreak;
1340 } 1334 }
1341 vmcase(OP_SETFIELD) { 1335 vmcase(OP_SETFIELD) {
1342 StkId ra = RA(i); 1336 StkId ra = RA(i);
1343 int aux; 1337 int hres;
1344 TValue *rb = KB(i); 1338 TValue *rb = KB(i);
1345 TValue *rc = RKC(i); 1339 TValue *rc = RKC(i);
1346 TString *key = tsvalue(rb); /* key must be a string */ 1340 TString *key = tsvalue(rb); /* key must be a string */
1347 luaV_fastset1(s2v(ra), key, rc, aux, luaH_setshortstr1); 1341 luaV_fastset(s2v(ra), key, rc, hres, luaH_psetshortstr);
1348 if (aux == HOK) 1342 if (hres == HOK)
1349 luaV_finishfastset1(L, s2v(ra), rc); 1343 luaV_finishfastset(L, s2v(ra), rc);
1350 else 1344 else
1351 Protect(luaV_finishset1(L, s2v(ra), rb, rc, aux)); 1345 Protect(luaV_finishset(L, s2v(ra), rb, rc, hres));
1352 vmbreak; 1346 vmbreak;
1353 } 1347 }
1354 vmcase(OP_NEWTABLE) { 1348 vmcase(OP_NEWTABLE) {
@@ -1372,14 +1366,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
1372 } 1366 }
1373 vmcase(OP_SELF) { 1367 vmcase(OP_SELF) {
1374 StkId ra = RA(i); 1368 StkId ra = RA(i);
1375 int aux; 1369 int hres;
1376 TValue *rb = vRB(i); 1370 TValue *rb = vRB(i);
1377 TValue *rc = RKC(i); 1371 TValue *rc = RKC(i);
1378 TString *key = tsvalue(rc); /* key must be a string */ 1372 TString *key = tsvalue(rc); /* key must be a string */
1379 setobj2s(L, ra + 1, rb); 1373 setobj2s(L, ra + 1, rb);
1380 luaV_fastget1(rb, key, s2v(ra), luaH_getstr1, aux); 1374 luaV_fastget(rb, key, s2v(ra), luaH_getstr, hres);
1381 if (aux != HOK) 1375 if (hres != HOK)
1382 Protect(luaV_finishget1(L, rb, rc, ra, aux)); 1376 Protect(luaV_finishget(L, rb, rc, ra, hres));
1383 vmbreak; 1377 vmbreak;
1384 } 1378 }
1385 vmcase(OP_ADDI) { 1379 vmcase(OP_ADDI) {
diff --git a/lvm.h b/lvm.h
index 750a22b2..8808c942 100644
--- a/lvm.h
+++ b/lvm.h
@@ -76,20 +76,9 @@ typedef enum {
76 76
77 77
78/* 78/*
79** fast track for 'gettable': if 't' is a table and 't[k]' is present, 79** fast track for 'gettable'
80** return 1 with 'slot' pointing to 't[k]' (position of final result).
81** Otherwise, return 0 (meaning it will have to check metamethod)
82** with 'slot' pointing to an empty 't[k]' (if 't' is a table) or NULL
83** (otherwise). 'f' is the raw get function to use.
84*/ 80*/
85#define luaV_fastget(L,t,k,slot,f) \ 81#define luaV_fastget(t,k,res,f, aux) \
86 (!ttistable(t) \
87 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
88 : (slot = f(hvalue(t), k), /* else, do raw access */ \
89 !isempty(slot))) /* result not empty? */
90
91
92#define luaV_fastget1(t,k,res,f, aux) \
93 (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res))) 82 (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res)))
94 83
95 84
@@ -97,45 +86,33 @@ typedef enum {
97** Special case of 'luaV_fastget' for integers, inlining the fast case 86** Special case of 'luaV_fastget' for integers, inlining the fast case
98** of 'luaH_getint'. 87** of 'luaH_getint'.
99*/ 88*/
100#define luaV_fastgeti(L,t,k,slot) \ 89#define luaV_fastgeti(t,k,res,aux) \
101 (!ttistable(t) \
102 ? (slot = NULL, 0) /* not a table; 'slot' is NULL and result is 0 */ \
103 : (slot = (l_castS2U(k) - 1u < hvalue(t)->alimit) \
104 ? &hvalue(t)->array[k - 1] : luaH_getint(hvalue(t), k), \
105 !isempty(slot))) /* result not empty? */
106
107#define luaV_fastgeti1(t,k,res,aux) \
108 if (!ttistable(t)) aux = HNOTATABLE; \ 90 if (!ttistable(t)) aux = HNOTATABLE; \
109 else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \ 91 else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \
110 if ((u - 1u < h->alimit)) { \ 92 if ((u - 1u < h->alimit)) { \
111 int tag = *getArrTag(h,u); \ 93 int tag = *getArrTag(h,u); \
112 if (tagisempty(tag)) aux = HNOTFOUND; \ 94 if (tagisempty(tag)) aux = HNOTFOUND; \
113 else { arr2val(h, u, tag, res); aux = HOK; }} \ 95 else { arr2val(h, u, tag, res); aux = HOK; }} \
114 else { aux = luaH_getint1(h, u, res); }} 96 else { aux = luaH_getint(h, u, res); }}
115 97
116 98
117#define luaV_fastset1(t,k,val,aux,f) \ 99#define luaV_fastset(t,k,val,aux,f) \
118 (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val))) 100 (aux = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, val)))
119 101
120#define luaV_fastseti1(t,k,val,aux) \ 102#define luaV_fastseti(t,k,val,aux) \
121 if (!ttistable(t)) aux = HNOTATABLE; \ 103 if (!ttistable(t)) aux = HNOTATABLE; \
122 else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \ 104 else { Table *h = hvalue(t); lua_Unsigned u = l_castS2U(k); \
123 if ((u - 1u < h->alimit)) { \ 105 if ((u - 1u < h->alimit)) { \
124 lu_byte *tag = getArrTag(h,u); \ 106 lu_byte *tag = getArrTag(h,u); \
125 if (tagisempty(*tag)) aux = ~cast_int(u); \ 107 if (tagisempty(*tag)) aux = ~cast_int(u); \
126 else { val2arr(h, u, tag, val); aux = HOK; }} \ 108 else { val2arr(h, u, tag, val); aux = HOK; }} \
127 else { aux = luaH_setint1(h, u, val); }} 109 else { aux = luaH_psetint(h, u, val); }}
128 110
129 111
130/* 112/*
131** Finish a fast set operation (when fast get succeeds). In that case, 113** Finish a fast set operation (when fast set succeeds).
132** 'slot' points to the place to put the value.
133*/ 114*/
134#define luaV_finishfastset(L,t,slot,v) \ 115#define luaV_finishfastset(L,t,v) luaC_barrierback(L, gcvalue(t), v)
135 { setobj2t(L, cast(TValue *,slot), v); \
136 luaC_barrierback(L, gcvalue(t), v); }
137
138#define luaV_finishfastset1(L,t,v) luaC_barrierback(L, gcvalue(t), v)
139 116
140 117
141/* 118/*
@@ -153,10 +130,10 @@ LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode);
153LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, 130LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p,
154 F2Imod mode); 131 F2Imod mode);
155LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); 132LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode);
156LUAI_FUNC void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, 133LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
157 StkId val, int aux); 134 StkId val, int aux);
158LUAI_FUNC void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key, 135LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
159 TValue *val, int aux); 136 TValue *val, int aux);
160LUAI_FUNC void luaV_finishOp (lua_State *L); 137LUAI_FUNC void luaV_finishOp (lua_State *L);
161LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); 138LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci);
162LUAI_FUNC void luaV_concat (lua_State *L, int total); 139LUAI_FUNC void luaV_concat (lua_State *L, int total);