aboutsummaryrefslogtreecommitdiff
path: root/lapi.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-20 13:52:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-20 13:52:50 -0300
commitca6fe7449a74efde6f959605dbe77acf3e64ca0b (patch)
treea6190e813ff712f7db750d4ecd3afd3ac9c0dbab /lapi.c
parent1afd5a152dc8b3a304236dc4e07bca38ea5eb53a (diff)
downloadlua-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.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/lapi.c b/lapi.c
index 1ec649b0..78ae7e0b 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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
736LUA_API int lua_getuservalue (lua_State *L, int idx) { 737LUA_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
906LUA_API void lua_setuservalue (lua_State *L, int idx) { 915LUA_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
1234LUA_API void *lua_newuserdata (lua_State *L, size_t size) { 1250LUA_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);