diff options
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 102 |
1 files changed, 52 insertions, 50 deletions
@@ -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); |