diff options
-rw-r--r-- | lapi.c | 70 | ||||
-rw-r--r-- | lcode.c | 8 | ||||
-rw-r--r-- | llex.c | 10 | ||||
-rw-r--r-- | ltable.c | 102 | ||||
-rw-r--r-- | ltable.h | 37 | ||||
-rw-r--r-- | ltm.c | 11 | ||||
-rw-r--r-- | lvm.c | 112 | ||||
-rw-r--r-- | lvm.h | 49 |
8 files changed, 189 insertions, 210 deletions
@@ -637,16 +637,16 @@ LUA_API int lua_pushthread (lua_State *L) { | |||
637 | 637 | ||
638 | 638 | ||
639 | l_sinline int auxgetstr (lua_State *L, const TValue *t, const char *k) { | 639 | l_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 | ||
674 | LUA_API int lua_gettable (lua_State *L, int idx) { | 674 | LUA_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 | ||
693 | LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { | 693 | LUA_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 | ||
710 | l_sinline int finishrawget (lua_State *L, const TValue *val) { | 710 | l_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 | ||
728 | LUA_API int lua_rawget (lua_State *L, int idx) { | 726 | LUA_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 | */ |
825 | static void auxsetstr (lua_State *L, const TValue *t, const char *k) { | 823 | static 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 | ||
852 | LUA_API void lua_settable (lua_State *L, int idx) { | 850 | LUA_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 | ||
875 | LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { | 873 | LUA_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); |
@@ -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); |
@@ -134,13 +134,13 @@ l_noret luaX_syntaxerror (LexState *ls, const char *msg) { | |||
134 | TString *luaX_newstring (LexState *ls, const char *str, size_t l) { | 134 | TString *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 */ |
@@ -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 | */ |
759 | const TValue *luaH_getint (Table *t, lua_Integer key) { | 759 | static 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 | ||
778 | int luaH_getint1 (Table *t, lua_Integer key, TValue *res) { | 778 | int 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 | */ |
786 | const TValue *luaH_getshortstr (Table *t, TString *key) { | 786 | const 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 | ||
802 | int luaH_getshortstr1 (Table *t, TString *key, TValue *res) { | 802 | int 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 | ||
807 | const TValue *luaH_getstr (Table *t, TString *key) { | 807 | static 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 | ||
818 | int luaH_getstr1 (Table *t, TString *key, TValue *res) { | 818 | int 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 | |||
823 | TString *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 | */ |
826 | const TValue *luaH_get (Table *t, const TValue *key) { | 835 | static 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 | ||
843 | int luaH_get1 (Table *t, const TValue *key, TValue *res) { | 852 | int 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 | ||
859 | int luaH_setint1 (Table *t, lua_Integer key, TValue *val) { | 868 | int 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 | ||
874 | int luaH_setshortstr1 (Table *t, TString *key, TValue *val) { | 883 | int 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 | ||
879 | int luaH_setstr1 (Table *t, TString *key, TValue *val) { | 888 | int 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 | ||
884 | int luaH_set1 (Table *t, const TValue *key, TValue *val) { | 893 | int 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 | */ |
906 | void 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 | ||
915 | void luaH_finishset1 (lua_State *L, Table *t, const TValue *key, | 917 | void 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 | */ |
934 | void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { | 937 | void 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 | ||
940 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | 944 | void 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); |
@@ -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 | ||
58 | LUAI_FUNC int luaH_getshortstr1 (Table *t, TString *key, TValue *res); | 68 | LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res); |
59 | LUAI_FUNC int luaH_getstr1 (Table *t, TString *key, TValue *res); | 69 | LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res); |
60 | LUAI_FUNC int luaH_get1 (Table *t, const TValue *key, TValue *res); | 70 | LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res); |
61 | LUAI_FUNC int luaH_getint1 (Table *t, lua_Integer key, TValue *res); | 71 | LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res); |
72 | |||
73 | LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key); | ||
62 | 74 | ||
63 | LUAI_FUNC int luaH_setint1 (Table *t, lua_Integer key, TValue *val); | 75 | LUAI_FUNC int luaH_psetint (Table *t, lua_Integer key, TValue *val); |
64 | LUAI_FUNC int luaH_setshortstr1 (Table *t, TString *key, TValue *val); | 76 | LUAI_FUNC int luaH_psetshortstr (Table *t, TString *key, TValue *val); |
65 | LUAI_FUNC int luaH_setstr1 (Table *t, TString *key, TValue *val); | 77 | LUAI_FUNC int luaH_psetstr (Table *t, TString *key, TValue *val); |
66 | LUAI_FUNC int luaH_set1 (Table *t, const TValue *key, TValue *val); | 78 | LUAI_FUNC int luaH_pset (Table *t, const TValue *key, TValue *val); |
67 | 79 | ||
68 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | ||
69 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | 80 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, |
70 | TValue *value); | 81 | TValue *value); |
71 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); | 82 | LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); |
72 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); | ||
73 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); | ||
74 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, | 83 | LUAI_FUNC void luaH_newkey (lua_State *L, Table *t, const TValue *key, |
75 | TValue *value); | 84 | TValue *value); |
76 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, | 85 | LUAI_FUNC void luaH_set (lua_State *L, Table *t, const TValue *key, |
77 | TValue *value); | 86 | TValue *value); |
78 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, | 87 | LUAI_FUNC void luaH_finishset (lua_State *L, Table *t, const TValue *key, |
79 | const TValue *slot, TValue *value); | ||
80 | LUAI_FUNC void luaH_finishset1 (lua_State *L, Table *t, const TValue *key, | ||
81 | TValue *value, int aux); | 88 | TValue *value, int aux); |
82 | LUAI_FUNC Table *luaH_new (lua_State *L); | 89 | LUAI_FUNC Table *luaH_new (lua_State *L); |
83 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | 90 | LUAI_FUNC void luaH_resize (lua_State *L, Table *t, unsigned int nasize, |
@@ -58,7 +58,7 @@ void luaT_init (lua_State *L) { | |||
58 | ** tag methods | 58 | ** tag methods |
59 | */ | 59 | */ |
60 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { | 60 | const 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 | } |
@@ -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 | */ |
287 | void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, StkId val, | 285 | void 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 | */ |
328 | void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key, | 322 | void 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) { |
@@ -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); | |||
153 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, | 130 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, |
154 | F2Imod mode); | 131 | F2Imod mode); |
155 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); | 132 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); |
156 | LUAI_FUNC void luaV_finishget1 (lua_State *L, const TValue *t, TValue *key, | 133 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, |
157 | StkId val, int aux); | 134 | StkId val, int aux); |
158 | LUAI_FUNC void luaV_finishset1 (lua_State *L, const TValue *t, TValue *key, | 135 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, |
159 | TValue *val, int aux); | 136 | TValue *val, int aux); |
160 | LUAI_FUNC void luaV_finishOp (lua_State *L); | 137 | LUAI_FUNC void luaV_finishOp (lua_State *L); |
161 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); | 138 | LUAI_FUNC void luaV_execute (lua_State *L, CallInfo *ci); |
162 | LUAI_FUNC void luaV_concat (lua_State *L, int total); | 139 | LUAI_FUNC void luaV_concat (lua_State *L, int total); |