diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-20 13:52:50 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2018-02-20 13:52:50 -0300 |
commit | ca6fe7449a74efde6f959605dbe77acf3e64ca0b (patch) | |
tree | a6190e813ff712f7db750d4ecd3afd3ac9c0dbab /lapi.c | |
parent | 1afd5a152dc8b3a304236dc4e07bca38ea5eb53a (diff) | |
download | lua-ca6fe7449a74efde6f959605dbe77acf3e64ca0b.tar.gz lua-ca6fe7449a74efde6f959605dbe77acf3e64ca0b.tar.bz2 lua-ca6fe7449a74efde6f959605dbe77acf3e64ca0b.zip |
userdata can have multiple user values
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 35 |
1 files changed, 26 insertions, 9 deletions
@@ -10,6 +10,7 @@ | |||
10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
11 | 11 | ||
12 | 12 | ||
13 | #include <limits.h> | ||
13 | #include <stdarg.h> | 14 | #include <stdarg.h> |
14 | #include <string.h> | 15 | #include <string.h> |
15 | 16 | ||
@@ -733,15 +734,23 @@ LUA_API int lua_getmetatable (lua_State *L, int objindex) { | |||
733 | } | 734 | } |
734 | 735 | ||
735 | 736 | ||
736 | LUA_API int lua_getuservalue (lua_State *L, int idx) { | 737 | LUA_API int lua_getiuservalue (lua_State *L, int idx, int n) { |
737 | TValue *o; | 738 | TValue *o; |
739 | int t; | ||
738 | lua_lock(L); | 740 | lua_lock(L); |
739 | o = index2value(L, idx); | 741 | o = index2value(L, idx); |
740 | api_check(L, ttisfulluserdata(o), "full userdata expected"); | 742 | api_check(L, ttisfulluserdata(o), "full userdata expected"); |
741 | getuservalue(L, uvalue(o), s2v(L->top)); | 743 | if (n <= 0 || n > uvalue(o)->nuvalue) { |
744 | setnilvalue(s2v(L->top)); | ||
745 | t = LUA_TNONE; | ||
746 | } | ||
747 | else { | ||
748 | setobj2s(L, L->top, &uvalue(o)->uv[n - 1].uv); | ||
749 | t = ttnov(s2v(L->top)); | ||
750 | } | ||
742 | api_incr_top(L); | 751 | api_incr_top(L); |
743 | lua_unlock(L); | 752 | lua_unlock(L); |
744 | return ttnov(s2v(L->top - 1)); | 753 | return t; |
745 | } | 754 | } |
746 | 755 | ||
747 | 756 | ||
@@ -903,16 +912,23 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
903 | } | 912 | } |
904 | 913 | ||
905 | 914 | ||
906 | LUA_API void lua_setuservalue (lua_State *L, int idx) { | 915 | LUA_API int lua_setiuservalue (lua_State *L, int idx, int n) { |
907 | TValue *o; | 916 | TValue *o; |
917 | int res; | ||
908 | lua_lock(L); | 918 | lua_lock(L); |
909 | api_checknelems(L, 1); | 919 | api_checknelems(L, 1); |
910 | o = index2value(L, idx); | 920 | o = index2value(L, idx); |
911 | api_check(L, ttisfulluserdata(o), "full userdata expected"); | 921 | api_check(L, ttisfulluserdata(o), "full userdata expected"); |
912 | setuservalue(L, uvalue(o), s2v(L->top - 1)); | 922 | if (!(0 < n && n <= uvalue(o)->nuvalue)) |
913 | luaC_barrier(L, gcvalue(o), s2v(L->top - 1)); | 923 | res = 0; |
914 | L->top--; | 924 | else { |
925 | setobj(L, &uvalue(o)->uv[n - 1].uv, s2v(L->top - 1)); | ||
926 | luaC_barrierback(L, gcvalue(o), s2v(L->top - 1)); | ||
927 | L->top--; | ||
928 | res = 1; | ||
929 | } | ||
915 | lua_unlock(L); | 930 | lua_unlock(L); |
931 | return res; | ||
916 | } | 932 | } |
917 | 933 | ||
918 | 934 | ||
@@ -1231,10 +1247,11 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud) { | |||
1231 | } | 1247 | } |
1232 | 1248 | ||
1233 | 1249 | ||
1234 | LUA_API void *lua_newuserdata (lua_State *L, size_t size) { | 1250 | LUA_API void *lua_newuserdatauv (lua_State *L, size_t size, int nuvalue) { |
1235 | Udata *u; | 1251 | Udata *u; |
1236 | lua_lock(L); | 1252 | lua_lock(L); |
1237 | u = luaS_newudata(L, size); | 1253 | api_check(L, 0 <= nuvalue && nuvalue < USHRT_MAX, "invalid value"); |
1254 | u = luaS_newudata(L, size, nuvalue); | ||
1238 | setuvalue(L, s2v(L->top), u); | 1255 | setuvalue(L, s2v(L->top), u); |
1239 | api_incr_top(L); | 1256 | api_incr_top(L); |
1240 | luaC_checkGC(L); | 1257 | luaC_checkGC(L); |