diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-03-18 15:56:32 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-03-18 15:56:32 -0300 |
| commit | ce6f5502c99ce9a367e25b678e375db6f8164d73 (patch) | |
| tree | 47f36dc2f6da96dfda325d7b587f3a20599e9317 | |
| parent | ba710603811c68fe3a69b3bb98e9038d37489a79 (diff) | |
| download | lua-ce6f5502c99ce9a367e25b678e375db6f8164d73.tar.gz lua-ce6f5502c99ce9a367e25b678e375db6f8164d73.tar.bz2 lua-ce6f5502c99ce9a367e25b678e375db6f8164d73.zip | |
'luaH_get' functions return 'TValue'
Instead of receiving a parameter telling them where to put the result
of the query, these functions return the TValue directly. (That is,
they return a structure.)
| -rw-r--r-- | lapi.c | 61 | ||||
| -rw-r--r-- | lcode.c | 5 | ||||
| -rw-r--r-- | ldump.c | 4 | ||||
| -rw-r--r-- | lobject.h | 19 | ||||
| -rw-r--r-- | ltable.c | 53 | ||||
| -rw-r--r-- | ltable.h | 29 | ||||
| -rw-r--r-- | lundump.c | 3 | ||||
| -rw-r--r-- | lvm.c | 54 | ||||
| -rw-r--r-- | lvm.h | 18 |
9 files changed, 124 insertions, 122 deletions
| @@ -666,47 +666,45 @@ LUA_API int lua_pushthread (lua_State *L) { | |||
| 666 | 666 | ||
| 667 | 667 | ||
| 668 | static int auxgetstr (lua_State *L, const TValue *t, const char *k) { | 668 | static int auxgetstr (lua_State *L, const TValue *t, const char *k) { |
| 669 | int hres; | 669 | TValue aux; |
| 670 | TString *str = luaS_new(L, k); | 670 | TString *str = luaS_new(L, k); |
| 671 | luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, hres); | 671 | luaV_fastget(t, str, s2v(L->top.p), luaH_getstr, aux); |
| 672 | if (hres == HOK) { | 672 | if (!isemptyV(aux)) { |
| 673 | api_incr_top(L); | 673 | api_incr_top(L); |
| 674 | } | 674 | } |
| 675 | else { | 675 | else { |
| 676 | setsvalue2s(L, L->top.p, str); | 676 | setsvalue2s(L, L->top.p, str); |
| 677 | api_incr_top(L); | 677 | api_incr_top(L); |
| 678 | luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, hres); | 678 | luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, aux); |
| 679 | } | 679 | } |
| 680 | lua_unlock(L); | 680 | lua_unlock(L); |
| 681 | return ttype(s2v(L->top.p - 1)); | 681 | return ttype(s2v(L->top.p - 1)); |
| 682 | } | 682 | } |
| 683 | 683 | ||
| 684 | 684 | ||
| 685 | static void getGlobalTable (lua_State *L, TValue *gt) { | 685 | static TValue getGlobalTable (lua_State *L) { |
| 686 | Table *registry = hvalue(&G(L)->l_registry); | 686 | Table *registry = hvalue(&G(L)->l_registry); |
| 687 | int hres = luaH_getint(registry, LUA_RIDX_GLOBALS, gt); | 687 | return luaH_getint(registry, LUA_RIDX_GLOBALS); |
| 688 | (void)hres; /* avoid warnings (not used) when checks are off */ | ||
| 689 | api_check(L, hres == HOK, "global table must exist"); | ||
| 690 | } | 688 | } |
| 691 | 689 | ||
| 692 | 690 | ||
| 693 | LUA_API int lua_getglobal (lua_State *L, const char *name) { | 691 | LUA_API int lua_getglobal (lua_State *L, const char *name) { |
| 694 | TValue gt; | 692 | TValue gt; |
| 695 | lua_lock(L); | 693 | lua_lock(L); |
| 696 | getGlobalTable(L, >); | 694 | gt = getGlobalTable(L); |
| 697 | return auxgetstr(L, >, name); | 695 | return auxgetstr(L, >, name); |
| 698 | } | 696 | } |
| 699 | 697 | ||
| 700 | 698 | ||
| 701 | LUA_API int lua_gettable (lua_State *L, int idx) { | 699 | LUA_API int lua_gettable (lua_State *L, int idx) { |
| 702 | int hres; | 700 | TValue aux; |
| 703 | TValue *t; | 701 | TValue *t; |
| 704 | lua_lock(L); | 702 | lua_lock(L); |
| 705 | api_checkpop(L, 1); | 703 | api_checkpop(L, 1); |
| 706 | t = index2value(L, idx); | 704 | t = index2value(L, idx); |
| 707 | luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, hres); | 705 | luaV_fastget(t, s2v(L->top.p - 1), s2v(L->top.p - 1), luaH_get, aux); |
| 708 | if (hres != HOK) | 706 | if (isemptyV(aux)) |
| 709 | luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, hres); | 707 | luaV_finishget(L, t, s2v(L->top.p - 1), L->top.p - 1, aux); |
| 710 | lua_unlock(L); | 708 | lua_unlock(L); |
| 711 | return ttype(s2v(L->top.p - 1)); | 709 | return ttype(s2v(L->top.p - 1)); |
| 712 | } | 710 | } |
| @@ -720,14 +718,14 @@ LUA_API int lua_getfield (lua_State *L, int idx, const char *k) { | |||
| 720 | 718 | ||
| 721 | LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { | 719 | LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { |
| 722 | TValue *t; | 720 | TValue *t; |
| 723 | int hres; | 721 | TValue aux; |
| 724 | lua_lock(L); | 722 | lua_lock(L); |
| 725 | t = index2value(L, idx); | 723 | t = index2value(L, idx); |
| 726 | luaV_fastgeti(t, n, s2v(L->top.p), hres); | 724 | luaV_fastgeti(t, n, s2v(L->top.p), aux); |
| 727 | if (hres != HOK) { | 725 | if (isemptyV(aux)) { |
| 728 | TValue key; | 726 | TValue key; |
| 729 | setivalue(&key, n); | 727 | setivalue(&key, n); |
| 730 | luaV_finishget(L, t, &key, L->top.p, hres); | 728 | luaV_finishget(L, t, &key, L->top.p, aux); |
| 731 | } | 729 | } |
| 732 | api_incr_top(L); | 730 | api_incr_top(L); |
| 733 | lua_unlock(L); | 731 | lua_unlock(L); |
| @@ -735,12 +733,14 @@ LUA_API int lua_geti (lua_State *L, int idx, lua_Integer n) { | |||
| 735 | } | 733 | } |
| 736 | 734 | ||
| 737 | 735 | ||
| 738 | l_sinline int finishrawget (lua_State *L, int hres) { | 736 | l_sinline int finishrawget (lua_State *L, TValue res) { |
| 739 | if (hres != HOK) /* avoid copying empty items to the stack */ | 737 | if (isemptyV(res)) /* avoid copying empty items to the stack */ |
| 740 | setnilvalue(s2v(L->top.p)); | 738 | setnilvalue(s2v(L->top.p)); |
| 739 | else | ||
| 740 | setobjV(L, s2v(L->top.p), res); | ||
| 741 | api_incr_top(L); | 741 | api_incr_top(L); |
| 742 | lua_unlock(L); | 742 | lua_unlock(L); |
| 743 | return ttype(s2v(L->top.p - 1)); | 743 | return ttypeV(res); |
| 744 | } | 744 | } |
| 745 | 745 | ||
| 746 | 746 | ||
| @@ -753,23 +753,23 @@ l_sinline Table *gettable (lua_State *L, int idx) { | |||
| 753 | 753 | ||
| 754 | LUA_API int lua_rawget (lua_State *L, int idx) { | 754 | LUA_API int lua_rawget (lua_State *L, int idx) { |
| 755 | Table *t; | 755 | Table *t; |
| 756 | TValue res; | ||
| 756 | lua_lock(L); | 757 | lua_lock(L); |
| 757 | api_checkpop(L, 1); | 758 | api_checkpop(L, 1); |
| 758 | t = gettable(L, idx); | 759 | t = gettable(L, idx); |
| 759 | if (luaH_get(t, s2v(L->top.p - 1), s2v(L->top.p - 1)) != HOK) | 760 | res = luaH_get(t, s2v(L->top.p - 1)); |
| 760 | setnilvalue(s2v(L->top.p - 1)); | 761 | L->top.p--; /* pop key */ |
| 761 | lua_unlock(L); | 762 | return finishrawget(L, res); |
| 762 | return ttype(s2v(L->top.p - 1)); | ||
| 763 | } | 763 | } |
| 764 | 764 | ||
| 765 | 765 | ||
| 766 | LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { | 766 | LUA_API int lua_rawgeti (lua_State *L, int idx, lua_Integer n) { |
| 767 | Table *t; | 767 | Table *t; |
| 768 | int hres; | 768 | TValue aux; |
| 769 | lua_lock(L); | 769 | lua_lock(L); |
| 770 | t = gettable(L, idx); | 770 | t = gettable(L, idx); |
| 771 | luaH_fastgeti(t, n, s2v(L->top.p), hres); | 771 | luaH_fastgeti(t, n, s2v(L->top.p), aux); |
| 772 | return finishrawget(L, hres); | 772 | return finishrawget(L, aux); |
| 773 | } | 773 | } |
| 774 | 774 | ||
| 775 | 775 | ||
| @@ -779,7 +779,7 @@ LUA_API int lua_rawgetp (lua_State *L, int idx, const void *p) { | |||
| 779 | lua_lock(L); | 779 | lua_lock(L); |
| 780 | t = gettable(L, idx); | 780 | t = gettable(L, idx); |
| 781 | setpvalue(&k, cast_voidp(p)); | 781 | setpvalue(&k, cast_voidp(p)); |
| 782 | return finishrawget(L, luaH_get(t, &k, s2v(L->top.p))); | 782 | return finishrawget(L, luaH_get(t, &k)); |
| 783 | } | 783 | } |
| 784 | 784 | ||
| 785 | 785 | ||
| @@ -872,7 +872,7 @@ static void auxsetstr (lua_State *L, const TValue *t, const char *k) { | |||
| 872 | LUA_API void lua_setglobal (lua_State *L, const char *name) { | 872 | LUA_API void lua_setglobal (lua_State *L, const char *name) { |
| 873 | TValue gt; | 873 | TValue gt; |
| 874 | lua_lock(L); /* unlock done in 'auxsetstr' */ | 874 | lua_lock(L); /* unlock done in 'auxsetstr' */ |
| 875 | getGlobalTable(L, >); | 875 | gt = getGlobalTable(L); |
| 876 | auxsetstr(L, >, name); | 876 | auxsetstr(L, >, name); |
| 877 | } | 877 | } |
| 878 | 878 | ||
| @@ -1122,8 +1122,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data, | |||
| 1122 | LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */ | 1122 | LClosure *f = clLvalue(s2v(L->top.p - 1)); /* get new function */ |
| 1123 | if (f->nupvalues >= 1) { /* does it have an upvalue? */ | 1123 | if (f->nupvalues >= 1) { /* does it have an upvalue? */ |
| 1124 | /* get global table from registry */ | 1124 | /* get global table from registry */ |
| 1125 | TValue gt; | 1125 | TValue gt = getGlobalTable(L); |
| 1126 | getGlobalTable(L, >); | ||
| 1127 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ | 1126 | /* set global table as 1st upvalue of 'f' (may be LUA_ENV) */ |
| 1128 | setobj(L, f->upvals[0]->v.p, >); | 1127 | setobj(L, f->upvals[0]->v.p, >); |
| 1129 | luaC_barrier(L, f->upvals[0], >); | 1128 | luaC_barrier(L, f->upvals[0], >); |
| @@ -541,12 +541,11 @@ static void freeexps (FuncState *fs, expdesc *e1, expdesc *e2) { | |||
| 541 | ** a function can make some indices wrong. | 541 | ** a function can make some indices wrong. |
| 542 | */ | 542 | */ |
| 543 | static int addk (FuncState *fs, TValue *key, TValue *v) { | 543 | static int addk (FuncState *fs, TValue *key, TValue *v) { |
| 544 | TValue val; | ||
| 545 | lua_State *L = fs->ls->L; | 544 | lua_State *L = fs->ls->L; |
| 546 | Proto *f = fs->f; | 545 | Proto *f = fs->f; |
| 547 | int aux = luaH_get(fs->ls->h, key, &val); /* query scanner table */ | 546 | TValue val = luaH_get(fs->ls->h, key); /* query scanner table */ |
| 548 | int k, oldsize; | 547 | int k, oldsize; |
| 549 | if (aux == HOK && ttisinteger(&val)) { /* is there an index there? */ | 548 | if (ttisintegerV(val)) { /* is there an index there? */ |
| 550 | k = cast_int(ivalue(&val)); | 549 | k = cast_int(ivalue(&val)); |
| 551 | /* correct value? (warning: must distinguish floats from integers!) */ | 550 | /* correct value? (warning: must distinguish floats from integers!) */ |
| 552 | if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && | 551 | if (k < fs->nk && ttypetag(&f->k[k]) == ttypetag(v) && |
| @@ -132,8 +132,8 @@ static void dumpString (DumpState *D, TString *ts) { | |||
| 132 | if (ts == NULL) | 132 | if (ts == NULL) |
| 133 | dumpSize(D, 0); | 133 | dumpSize(D, 0); |
| 134 | else { | 134 | else { |
| 135 | TValue idx; | 135 | TValue idx = luaH_getstr(D->h, ts); |
| 136 | if (luaH_getstr(D->h, ts, &idx) == HOK) { /* string already saved? */ | 136 | if (!isemptyV(idx)) { /* string already saved? */ |
| 137 | dumpSize(D, 1); /* reuse a saved string */ | 137 | dumpSize(D, 1); /* reuse a saved string */ |
| 138 | dumpSize(D, cast_sizet(ivalue(&idx))); /* index of saved string */ | 138 | dumpSize(D, cast_sizet(ivalue(&idx))); /* index of saved string */ |
| 139 | } | 139 | } |
| @@ -75,6 +75,7 @@ typedef struct TValue { | |||
| 75 | 75 | ||
| 76 | /* raw type tag of a TValue */ | 76 | /* raw type tag of a TValue */ |
| 77 | #define rawtt(o) ((o)->tt_) | 77 | #define rawtt(o) ((o)->tt_) |
| 78 | #define rawttV(o) ((o).tt_) | ||
| 78 | 79 | ||
| 79 | /* tag with no variants (bits 0-3) */ | 80 | /* tag with no variants (bits 0-3) */ |
| 80 | #define novariant(t) ((t) & 0x0F) | 81 | #define novariant(t) ((t) & 0x0F) |
| @@ -82,14 +83,18 @@ typedef struct TValue { | |||
| 82 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ | 83 | /* type tag of a TValue (bits 0-3 for tags + variant bits 4-5) */ |
| 83 | #define withvariant(t) ((t) & 0x3F) | 84 | #define withvariant(t) ((t) & 0x3F) |
| 84 | #define ttypetag(o) withvariant(rawtt(o)) | 85 | #define ttypetag(o) withvariant(rawtt(o)) |
| 86 | #define ttypetagV(o) withvariant(rawttV(o)) | ||
| 85 | 87 | ||
| 86 | /* type of a TValue */ | 88 | /* type of a TValue */ |
| 87 | #define ttype(o) (novariant(rawtt(o))) | 89 | #define ttype(o) (novariant(rawtt(o))) |
| 90 | #define ttypeV(o) (novariant(rawttV(o))) | ||
| 88 | 91 | ||
| 89 | 92 | ||
| 90 | /* Macros to test type */ | 93 | /* Macros to test type */ |
| 91 | #define checktag(o,t) (rawtt(o) == (t)) | 94 | #define checktag(o,t) (rawtt(o) == (t)) |
| 95 | #define checktagV(o,t) (rawttV(o) == (t)) | ||
| 92 | #define checktype(o,t) (ttype(o) == (t)) | 96 | #define checktype(o,t) (ttype(o) == (t)) |
| 97 | #define checktypeV(o,t) (ttypeV(o) == (t)) | ||
| 93 | 98 | ||
| 94 | 99 | ||
| 95 | /* Macros for internal tests */ | 100 | /* Macros for internal tests */ |
| @@ -112,6 +117,7 @@ typedef struct TValue { | |||
| 112 | 117 | ||
| 113 | /* set a value's tag */ | 118 | /* set a value's tag */ |
| 114 | #define settt_(o,t) ((o)->tt_=(t)) | 119 | #define settt_(o,t) ((o)->tt_=(t)) |
| 120 | #define setttV_(o,t) ((o).tt_=(t)) | ||
| 115 | 121 | ||
| 116 | 122 | ||
| 117 | /* main macro to copy values (from 'obj2' to 'obj1') */ | 123 | /* main macro to copy values (from 'obj2' to 'obj1') */ |
| @@ -120,6 +126,11 @@ typedef struct TValue { | |||
| 120 | io1->value_ = io2->value_; settt_(io1, io2->tt_); \ | 126 | io1->value_ = io2->value_; settt_(io1, io2->tt_); \ |
| 121 | checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } | 127 | checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } |
| 122 | 128 | ||
| 129 | #define setobjV(L,obj1,obj2) \ | ||
| 130 | { TValue *io1=(obj1); const TValue io2=(obj2); \ | ||
| 131 | io1->value_ = io2.value_; settt_(io1, io2.tt_); \ | ||
| 132 | checkliveness(L,io1); lua_assert(!isnonstrictnil(io1)); } | ||
| 133 | |||
| 123 | /* | 134 | /* |
| 124 | ** Different types of assignments, according to source and destination. | 135 | ** Different types of assignments, according to source and destination. |
| 125 | ** (They are mostly equal now, but may be different in the future.) | 136 | ** (They are mostly equal now, but may be different in the future.) |
| @@ -188,9 +199,15 @@ typedef union { | |||
| 188 | /* Value returned for a key not found in a table (absent key) */ | 199 | /* Value returned for a key not found in a table (absent key) */ |
| 189 | #define LUA_VABSTKEY makevariant(LUA_TNIL, 2) | 200 | #define LUA_VABSTKEY makevariant(LUA_TNIL, 2) |
| 190 | 201 | ||
| 202 | /* Special "value" to signal that a fast get is accessing a non-table */ | ||
| 203 | #define LUA_VNOTABLE makevariant(LUA_TNIL, 3) | ||
| 204 | |||
| 205 | #define setnotableV(obj) setttV_(obj, LUA_VNOTABLE) | ||
| 206 | |||
| 191 | 207 | ||
| 192 | /* macro to test for (any kind of) nil */ | 208 | /* macro to test for (any kind of) nil */ |
| 193 | #define ttisnil(v) checktype((v), LUA_TNIL) | 209 | #define ttisnil(v) checktype((v), LUA_TNIL) |
| 210 | #define ttisnilV(v) checktypeV((v), LUA_TNIL) | ||
| 194 | 211 | ||
| 195 | #define tagisempty(tag) (novariant(tag) == LUA_TNIL) | 212 | #define tagisempty(tag) (novariant(tag) == LUA_TNIL) |
| 196 | 213 | ||
| @@ -217,6 +234,7 @@ typedef union { | |||
| 217 | ** be accepted as empty.) | 234 | ** be accepted as empty.) |
| 218 | */ | 235 | */ |
| 219 | #define isempty(v) ttisnil(v) | 236 | #define isempty(v) ttisnil(v) |
| 237 | #define isemptyV(v) checktypeV((v), LUA_TNIL) | ||
| 220 | 238 | ||
| 221 | 239 | ||
| 222 | /* macro defining a value corresponding to an absent key */ | 240 | /* macro defining a value corresponding to an absent key */ |
| @@ -328,6 +346,7 @@ typedef struct GCObject { | |||
| 328 | #define ttisnumber(o) checktype((o), LUA_TNUMBER) | 346 | #define ttisnumber(o) checktype((o), LUA_TNUMBER) |
| 329 | #define ttisfloat(o) checktag((o), LUA_VNUMFLT) | 347 | #define ttisfloat(o) checktag((o), LUA_VNUMFLT) |
| 330 | #define ttisinteger(o) checktag((o), LUA_VNUMINT) | 348 | #define ttisinteger(o) checktag((o), LUA_VNUMINT) |
| 349 | #define ttisintegerV(o) checktagV((o), LUA_VNUMINT) | ||
| 331 | 350 | ||
| 332 | #define nvalue(o) check_exp(ttisnumber(o), \ | 351 | #define nvalue(o) check_exp(ttisnumber(o), \ |
| 333 | (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) | 352 | (ttisinteger(o) ? cast_num(ivalue(o)) : fltvalue(o))) |
| @@ -904,28 +904,14 @@ static int hashkeyisempty (Table *t, lua_Integer key) { | |||
| 904 | } | 904 | } |
| 905 | 905 | ||
| 906 | 906 | ||
| 907 | static int finishnodeget (const TValue *val, TValue *res) { | 907 | TValue luaH_getint (Table *t, lua_Integer key) { |
| 908 | if (!ttisnil(val)) { | ||
| 909 | setobj(((lua_State*)NULL), res, val); | ||
| 910 | return HOK; /* success */ | ||
| 911 | } | ||
| 912 | else | ||
| 913 | return HNOTFOUND; /* could not get value */ | ||
| 914 | } | ||
| 915 | |||
| 916 | |||
| 917 | int luaH_getint (Table *t, lua_Integer key, TValue *res) { | ||
| 918 | if (keyinarray(t, key)) { | 908 | if (keyinarray(t, key)) { |
| 919 | int tag = *getArrTag(t, key - 1); | 909 | TValue res; |
| 920 | if (!tagisempty(tag)) { | 910 | arr2objV(t, key, res); |
| 921 | farr2val(t, key, tag, res); | 911 | return res; |
| 922 | return HOK; /* success */ | ||
| 923 | } | ||
| 924 | else | ||
| 925 | return ~cast_int(key); /* empty slot in the array part */ | ||
| 926 | } | 912 | } |
| 927 | else | 913 | else |
| 928 | return finishnodeget(getintfromhash(t, key), res); | 914 | return *getintfromhash(t, key); |
| 929 | } | 915 | } |
| 930 | 916 | ||
| 931 | 917 | ||
| @@ -948,8 +934,8 @@ const TValue *luaH_Hgetshortstr (Table *t, TString *key) { | |||
| 948 | } | 934 | } |
| 949 | 935 | ||
| 950 | 936 | ||
| 951 | int luaH_getshortstr (Table *t, TString *key, TValue *res) { | 937 | TValue luaH_getshortstr (Table *t, TString *key) { |
| 952 | return finishnodeget(luaH_Hgetshortstr(t, key), res); | 938 | return *luaH_Hgetshortstr(t, key); |
| 953 | } | 939 | } |
| 954 | 940 | ||
| 955 | 941 | ||
| @@ -964,8 +950,8 @@ static const TValue *Hgetstr (Table *t, TString *key) { | |||
| 964 | } | 950 | } |
| 965 | 951 | ||
| 966 | 952 | ||
| 967 | int luaH_getstr (Table *t, TString *key, TValue *res) { | 953 | TValue luaH_getstr (Table *t, TString *key) { |
| 968 | return finishnodeget(Hgetstr(t, key), res); | 954 | return *Hgetstr(t, key); |
| 969 | } | 955 | } |
| 970 | 956 | ||
| 971 | 957 | ||
| @@ -981,34 +967,31 @@ TString *luaH_getstrkey (Table *t, TString *key) { | |||
| 981 | /* | 967 | /* |
| 982 | ** main search function | 968 | ** main search function |
| 983 | */ | 969 | */ |
| 984 | int luaH_get (Table *t, const TValue *key, TValue *res) { | 970 | TValue luaH_get (Table *t, const TValue *key) { |
| 985 | const TValue *slot; | ||
| 986 | switch (ttypetag(key)) { | 971 | switch (ttypetag(key)) { |
| 987 | case LUA_VSHRSTR: | 972 | case LUA_VSHRSTR: |
| 988 | slot = luaH_Hgetshortstr(t, tsvalue(key)); | 973 | return *luaH_Hgetshortstr(t, tsvalue(key)); |
| 989 | break; | 974 | break; |
| 990 | case LUA_VNUMINT: | 975 | case LUA_VNUMINT: |
| 991 | return luaH_getint(t, ivalue(key), res); | 976 | return luaH_getint(t, ivalue(key)); |
| 992 | case LUA_VNIL: | 977 | case LUA_VNIL: |
| 993 | slot = &absentkey; | 978 | return absentkey; |
| 994 | break; | 979 | break; |
| 995 | case LUA_VNUMFLT: { | 980 | case LUA_VNUMFLT: { |
| 996 | lua_Integer k; | 981 | lua_Integer k; |
| 997 | if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ | 982 | if (luaV_flttointeger(fltvalue(key), &k, F2Ieq)) /* integral index? */ |
| 998 | return luaH_getint(t, k, res); /* use specialized version */ | 983 | return luaH_getint(t, k); /* use specialized version */ |
| 999 | /* else... */ | 984 | /* else... */ |
| 1000 | } /* FALLTHROUGH */ | 985 | } /* FALLTHROUGH */ |
| 1001 | default: | 986 | default: |
| 1002 | slot = getgeneric(t, key, 0); | 987 | return *getgeneric(t, key, 0); |
| 1003 | break; | ||
| 1004 | } | 988 | } |
| 1005 | return finishnodeget(slot, res); | ||
| 1006 | } | 989 | } |
| 1007 | 990 | ||
| 1008 | 991 | ||
| 1009 | static int finishnodeset (Table *t, const TValue *slot, TValue *val) { | 992 | static int finishnodeset (Table *t, const TValue *slot, TValue *val) { |
| 1010 | if (!ttisnil(slot)) { | 993 | if (!ttisnil(slot)) { |
| 1011 | setobj(((lua_State*)NULL), cast(TValue*, slot), val); | 994 | setobj(cast(lua_State*, NULL), cast(TValue*, slot), val); |
| 1012 | return HOK; /* success */ | 995 | return HOK; /* success */ |
| 1013 | } | 996 | } |
| 1014 | else if (isabstkey(slot)) | 997 | else if (isabstkey(slot)) |
| @@ -1022,7 +1005,7 @@ static int rawfinishnodeset (const TValue *slot, TValue *val) { | |||
| 1022 | if (isabstkey(slot)) | 1005 | if (isabstkey(slot)) |
| 1023 | return 0; /* no slot with that key */ | 1006 | return 0; /* no slot with that key */ |
| 1024 | else { | 1007 | else { |
| 1025 | setobj(((lua_State*)NULL), cast(TValue*, slot), val); | 1008 | setobj(cast(lua_State*, NULL), cast(TValue*, slot), val); |
| 1026 | return 1; /* success */ | 1009 | return 1; /* success */ |
| 1027 | } | 1010 | } |
| 1028 | } | 1011 | } |
| @@ -46,13 +46,11 @@ | |||
| 46 | 46 | ||
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | #define luaH_fastgeti(t,k,res,hres) \ | 49 | #define luaH_fastgeti(t,k,res,aux) \ |
| 50 | { Table *h = t; lua_Unsigned u = l_castS2U(k); \ | 50 | { Table *h = t; lua_Unsigned u = l_castS2U(k); \ |
| 51 | if ((u - 1u < h->alimit)) { \ | 51 | if ((u - 1u < h->alimit)) arr2objV(h,u,aux); \ |
| 52 | int tag = *getArrTag(h,(u)-1u); \ | 52 | else aux = luaH_getint(h, u); \ |
| 53 | if (tagisempty(tag)) hres = HNOTFOUND; \ | 53 | if (!isemptyV(aux)) setobjV(cast(lua_State*, NULL), res, aux); } |
| 54 | else { farr2val(h, u, tag, res); hres = HOK; }} \ | ||
| 55 | else { hres = luaH_getint(h, u, res); }} | ||
| 56 | 54 | ||
| 57 | 55 | ||
| 58 | #define luaH_fastseti(t,k,val,hres) \ | 56 | #define luaH_fastseti(t,k,val,hres) \ |
| @@ -64,15 +62,13 @@ | |||
| 64 | else { hres = luaH_psetint(h, u, val); }} | 62 | else { hres = luaH_psetint(h, u, val); }} |
| 65 | 63 | ||
| 66 | 64 | ||
| 67 | /* results from get/pset */ | 65 | /* results from pset */ |
| 68 | #define HOK 0 | 66 | #define HOK 0 |
| 69 | #define HNOTFOUND 1 | 67 | #define HNOTFOUND 1 |
| 70 | #define HNOTATABLE 2 | 68 | #define HNOTATABLE 2 |
| 71 | #define HFIRSTNODE 3 | 69 | #define HFIRSTNODE 3 |
| 72 | 70 | ||
| 73 | /* | 71 | /* |
| 74 | ** 'luaH_get*' operations set 'res' and return HOK, unless the value is | ||
| 75 | ** absent. In that case, they set nothing and return HNOTFOUND. | ||
| 76 | ** The 'luaH_pset*' (pre-set) operations set the given value and return | 72 | ** The 'luaH_pset*' (pre-set) operations set the given value and return |
| 77 | ** HOK, unless the original value is absent. In that case, if the key | 73 | ** HOK, unless the original value is absent. In that case, if the key |
| 78 | ** is really absent, they return HNOTFOUND. Otherwise, if there is a | 74 | ** is really absent, they return HNOTFOUND. Otherwise, if there is a |
| @@ -109,8 +105,10 @@ struct ArrayCell { | |||
| 109 | /* | 105 | /* |
| 110 | ** Move TValues to/from arrays, using Lua indices | 106 | ** Move TValues to/from arrays, using Lua indices |
| 111 | */ | 107 | */ |
| 112 | #define arr2obj(h,k,val) \ | 108 | #define arr2objV(h,k,val) \ |
| 113 | ((val)->tt_ = *getArrTag(h,(k)-1u), (val)->value_ = *getArrVal(h,(k)-1u)) | 109 | ((val).tt_ = *getArrTag(h,(k)-1u), (val).value_ = *getArrVal(h,(k)-1u)) |
| 110 | |||
| 111 | #define arr2obj(h,k,val) arr2objV(h,k,*(val)) | ||
| 114 | 112 | ||
| 115 | #define obj2arr(h,k,val) \ | 113 | #define obj2arr(h,k,val) \ |
| 116 | (*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) | 114 | (*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) |
| @@ -128,12 +126,11 @@ struct ArrayCell { | |||
| 128 | (*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) | 126 | (*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) |
| 129 | 127 | ||
| 130 | 128 | ||
| 131 | LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res); | 129 | LUAI_FUNC TValue luaH_get (Table *t, const TValue *key); |
| 132 | LUAI_FUNC int luaH_getshortstr (Table *t, TString *key, TValue *res); | 130 | LUAI_FUNC TValue luaH_getshortstr (Table *t, TString *key); |
| 133 | LUAI_FUNC int luaH_getstr (Table *t, TString *key, TValue *res); | 131 | LUAI_FUNC TValue luaH_getstr (Table *t, TString *key); |
| 134 | LUAI_FUNC int luaH_getint (Table *t, lua_Integer key, TValue *res); | 132 | LUAI_FUNC TValue luaH_getint (Table *t, lua_Integer key); |
| 135 | 133 | ||
| 136 | /* Special get for metamethods */ | ||
| 137 | LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); | 134 | LUAI_FUNC const TValue *luaH_Hgetshortstr (Table *t, TString *key); |
| 138 | 135 | ||
| 139 | LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key); | 136 | LUAI_FUNC TString *luaH_getstrkey (Table *t, TString *key); |
| @@ -149,8 +149,7 @@ static void loadString (LoadState *S, Proto *p, TString **sl) { | |||
| 149 | } | 149 | } |
| 150 | else if (size == 1) { /* previously saved string? */ | 150 | else if (size == 1) { /* previously saved string? */ |
| 151 | lua_Integer idx = cast(lua_Integer, loadSize(S)); /* get its index */ | 151 | lua_Integer idx = cast(lua_Integer, loadSize(S)); /* get its index */ |
| 152 | TValue stv; | 152 | TValue stv = luaH_getint(S->h, idx); /* get its value */ |
| 153 | luaH_getint(S->h, idx, &stv); /* get its value */ | ||
| 154 | *sl = ts = tsvalue(&stv); | 153 | *sl = ts = tsvalue(&stv); |
| 155 | luaC_objbarrier(L, p, ts); | 154 | luaC_objbarrier(L, p, ts); |
| 156 | return; /* do not save it again */ | 155 | return; /* do not save it again */ |
| @@ -287,12 +287,13 @@ static int floatforloop (StkId ra) { | |||
| 287 | /* | 287 | /* |
| 288 | ** Finish the table access 'val = t[key]'. | 288 | ** Finish the table access 'val = t[key]'. |
| 289 | */ | 289 | */ |
| 290 | void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | 290 | void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key, StkId val, |
| 291 | int hres) { | 291 | int tag) { |
| 292 | int loop; /* counter to avoid infinite loops */ | 292 | int loop; /* counter to avoid infinite loops */ |
| 293 | const TValue *tm; /* metamethod */ | 293 | const TValue *tm; /* metamethod */ |
| 294 | TValue aux; | ||
| 294 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | 295 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 295 | if (hres == HNOTATABLE) { /* 't' is not a table? */ | 296 | if (tag == LUA_VNOTABLE) { /* 't' is not a table? */ |
| 296 | lua_assert(!ttistable(t)); | 297 | lua_assert(!ttistable(t)); |
| 297 | tm = luaT_gettmbyobj(L, t, TM_INDEX); | 298 | tm = luaT_gettmbyobj(L, t, TM_INDEX); |
| 298 | if (l_unlikely(notm(tm))) | 299 | if (l_unlikely(notm(tm))) |
| @@ -312,10 +313,11 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val, | |||
| 312 | return; | 313 | return; |
| 313 | } | 314 | } |
| 314 | t = tm; /* else try to access 'tm[key]' */ | 315 | t = tm; /* else try to access 'tm[key]' */ |
| 315 | luaV_fastget(t, key, s2v(val), luaH_get, hres); | 316 | luaV_fastget(t, key, s2v(val), luaH_get, aux); |
| 316 | if (hres == HOK) | 317 | if (!isemptyV(aux)) |
| 317 | return; /* done */ | 318 | return; /* done */ |
| 318 | /* else repeat (tail call 'luaV_finishget') */ | 319 | /* else repeat (tail call 'luaV_finishget') */ |
| 320 | tag = ttypetagV(aux); | ||
| 319 | } | 321 | } |
| 320 | luaG_runerror(L, "'__index' chain too long; possible loop"); | 322 | luaG_runerror(L, "'__index' chain too long; possible loop"); |
| 321 | } | 323 | } |
| @@ -1245,36 +1247,36 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1245 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; | 1247 | TValue *upval = cl->upvals[GETARG_B(i)]->v.p; |
| 1246 | TValue *rc = KC(i); | 1248 | TValue *rc = KC(i); |
| 1247 | TString *key = tsvalue(rc); /* key must be a short string */ | 1249 | TString *key = tsvalue(rc); /* key must be a short string */ |
| 1248 | int hres; | 1250 | TValue aux; |
| 1249 | luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, hres); | 1251 | luaV_fastget(upval, key, s2v(ra), luaH_getshortstr, aux); |
| 1250 | if (hres != HOK) | 1252 | if (isemptyV(aux)) |
| 1251 | Protect(luaV_finishget(L, upval, rc, ra, hres)); | 1253 | Protect(luaV_finishget(L, upval, rc, ra, aux)); |
| 1252 | vmbreak; | 1254 | vmbreak; |
| 1253 | } | 1255 | } |
| 1254 | vmcase(OP_GETTABLE) { | 1256 | vmcase(OP_GETTABLE) { |
| 1255 | StkId ra = RA(i); | 1257 | StkId ra = RA(i); |
| 1256 | TValue *rb = vRB(i); | 1258 | TValue *rb = vRB(i); |
| 1257 | TValue *rc = vRC(i); | 1259 | TValue *rc = vRC(i); |
| 1258 | int hres; | 1260 | TValue aux; |
| 1259 | if (ttisinteger(rc)) { /* fast track for integers? */ | 1261 | if (ttisinteger(rc)) { /* fast track for integers? */ |
| 1260 | luaV_fastgeti(rb, ivalue(rc), s2v(ra), hres); | 1262 | luaV_fastgeti(rb, ivalue(rc), s2v(ra), aux); |
| 1261 | } | 1263 | } |
| 1262 | else | 1264 | else |
| 1263 | luaV_fastget(rb, rc, s2v(ra), luaH_get, hres); | 1265 | luaV_fastget(rb, rc, s2v(ra), luaH_get, aux); |
| 1264 | if (hres != HOK) /* fast track for integers? */ | 1266 | if (isemptyV(aux)) /* fast track for integers? */ |
| 1265 | Protect(luaV_finishget(L, rb, rc, ra, hres)); | 1267 | Protect(luaV_finishget(L, rb, rc, ra, aux)); |
| 1266 | vmbreak; | 1268 | vmbreak; |
| 1267 | } | 1269 | } |
| 1268 | vmcase(OP_GETI) { | 1270 | vmcase(OP_GETI) { |
| 1269 | StkId ra = RA(i); | 1271 | StkId ra = RA(i); |
| 1270 | TValue *rb = vRB(i); | 1272 | TValue *rb = vRB(i); |
| 1271 | int c = GETARG_C(i); | 1273 | int c = GETARG_C(i); |
| 1272 | int hres; | 1274 | TValue aux; |
| 1273 | luaV_fastgeti(rb, c, s2v(ra), hres); | 1275 | luaV_fastgeti(rb, c, s2v(ra), aux); |
| 1274 | if (hres != HOK) { | 1276 | if (isemptyV(aux)) { |
| 1275 | TValue key; | 1277 | TValue key; |
| 1276 | setivalue(&key, c); | 1278 | setivalue(&key, c); |
| 1277 | Protect(luaV_finishget(L, rb, &key, ra, hres)); | 1279 | Protect(luaV_finishget(L, rb, &key, ra, aux)); |
| 1278 | } | 1280 | } |
| 1279 | vmbreak; | 1281 | vmbreak; |
| 1280 | } | 1282 | } |
| @@ -1283,10 +1285,10 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1283 | TValue *rb = vRB(i); | 1285 | TValue *rb = vRB(i); |
| 1284 | TValue *rc = KC(i); | 1286 | TValue *rc = KC(i); |
| 1285 | TString *key = tsvalue(rc); /* key must be a short string */ | 1287 | TString *key = tsvalue(rc); /* key must be a short string */ |
| 1286 | int hres; | 1288 | TValue aux; |
| 1287 | luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, hres); | 1289 | luaV_fastget(rb, key, s2v(ra), luaH_getshortstr, aux); |
| 1288 | if (hres != HOK) | 1290 | if (isemptyV(aux)) |
| 1289 | Protect(luaV_finishget(L, rb, rc, ra, hres)); | 1291 | Protect(luaV_finishget(L, rb, rc, ra, aux)); |
| 1290 | vmbreak; | 1292 | vmbreak; |
| 1291 | } | 1293 | } |
| 1292 | vmcase(OP_SETTABUP) { | 1294 | vmcase(OP_SETTABUP) { |
| @@ -1368,14 +1370,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1368 | } | 1370 | } |
| 1369 | vmcase(OP_SELF) { | 1371 | vmcase(OP_SELF) { |
| 1370 | StkId ra = RA(i); | 1372 | StkId ra = RA(i); |
| 1371 | int hres; | 1373 | TValue aux; |
| 1372 | TValue *rb = vRB(i); | 1374 | TValue *rb = vRB(i); |
| 1373 | TValue *rc = RKC(i); | 1375 | TValue *rc = RKC(i); |
| 1374 | TString *key = tsvalue(rc); /* key must be a string */ | 1376 | TString *key = tsvalue(rc); /* key must be a string */ |
| 1375 | setobj2s(L, ra + 1, rb); | 1377 | setobj2s(L, ra + 1, rb); |
| 1376 | luaV_fastget(rb, key, s2v(ra), luaH_getstr, hres); | 1378 | luaV_fastget(rb, key, s2v(ra), luaH_getstr, aux); |
| 1377 | if (hres != HOK) | 1379 | if (isemptyV(aux)) |
| 1378 | Protect(luaV_finishget(L, rb, rc, ra, hres)); | 1380 | Protect(luaV_finishget(L, rb, rc, ra, aux)); |
| 1379 | vmbreak; | 1381 | vmbreak; |
| 1380 | } | 1382 | } |
| 1381 | vmcase(OP_ADDI) { | 1383 | vmcase(OP_ADDI) { |
| @@ -78,17 +78,19 @@ typedef enum { | |||
| 78 | /* | 78 | /* |
| 79 | ** fast track for 'gettable' | 79 | ** fast track for 'gettable' |
| 80 | */ | 80 | */ |
| 81 | #define luaV_fastget(t,k,res,f, hres) \ | 81 | #define luaV_fastget(t,k,res,f, aux) \ |
| 82 | (hres = (!ttistable(t) ? HNOTATABLE : f(hvalue(t), k, res))) | 82 | {if (!ttistable(t)) setnotableV(aux); \ |
| 83 | else { aux = f(hvalue(t), k); \ | ||
| 84 | if (!isemptyV(aux)) { setobjV(cast(lua_State*, NULL), res, aux); } } } | ||
| 83 | 85 | ||
| 84 | 86 | ||
| 85 | /* | 87 | /* |
| 86 | ** Special case of 'luaV_fastget' for integers, inlining the fast case | 88 | ** Special case of 'luaV_fastget' for integers, inlining the fast case |
| 87 | ** of 'luaH_getint'. | 89 | ** of 'luaH_getint'. |
| 88 | */ | 90 | */ |
| 89 | #define luaV_fastgeti(t,k,res,hres) \ | 91 | #define luaV_fastgeti(t,k,res,aux) \ |
| 90 | if (!ttistable(t)) hres = HNOTATABLE; \ | 92 | { if (!ttistable(t)) setnotableV(aux); \ |
| 91 | else { luaH_fastgeti(hvalue(t), k, res, hres); } | 93 | else { luaH_fastgeti(hvalue(t), k, res, aux); } } |
| 92 | 94 | ||
| 93 | 95 | ||
| 94 | #define luaV_fastset(t,k,val,hres,f) \ | 96 | #define luaV_fastset(t,k,val,hres,f) \ |
| @@ -120,8 +122,10 @@ LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, F2Imod mode); | |||
| 120 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, | 122 | LUAI_FUNC int luaV_tointegerns (const TValue *obj, lua_Integer *p, |
| 121 | F2Imod mode); | 123 | F2Imod mode); |
| 122 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); | 124 | LUAI_FUNC int luaV_flttointeger (lua_Number n, lua_Integer *p, F2Imod mode); |
| 123 | LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, | 125 | #define luaV_finishget(L,t,key,val,aux) \ |
| 124 | StkId val, int aux); | 126 | luaV_finishget_(L,t,key,val,ttypetagV(aux)) |
| 127 | LUAI_FUNC void luaV_finishget_ (lua_State *L, const TValue *t, TValue *key, | ||
| 128 | StkId val, int tag); | ||
| 125 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, | 129 | LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key, |
| 126 | TValue *val, int aux); | 130 | TValue *val, int aux); |
| 127 | LUAI_FUNC void luaV_finishOp (lua_State *L); | 131 | LUAI_FUNC void luaV_finishOp (lua_State *L); |
