summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c52
-rw-r--r--lvm.c33
-rw-r--r--lvm.h21
3 files changed, 67 insertions, 39 deletions
diff --git a/lapi.c b/lapi.c
index 6e5a0d3d..f3c2b2f3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.250 2015/06/18 14:19:52 roberto Exp roberto $ 2** $Id: lapi.c,v 2.251 2015/07/20 18:24:50 roberto Exp roberto $
3** Lua API 3** Lua API
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -731,18 +731,28 @@ LUA_API int lua_getuservalue (lua_State *L, int idx) {
731** set functions (stack -> Lua) 731** set functions (stack -> Lua)
732*/ 732*/
733 733
734static void auxsetstr (lua_State *L, const TValue *t, const char *k) {
735 const TValue *aux;
736 TString *str = luaS_new(L, k);
737 api_checknelems(L, 1);
738 if (luaV_fastset(L, t, str, aux, luaH_getstr, L->top)) {
739 setobj2t(L, cast(TValue *, aux), L->top - 1);
740 L->top--; /* pop value */
741 }
742 else {
743 setsvalue2s(L, L->top, str);
744 api_incr_top(L);
745 luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
746 L->top -= 2; /* pop value and key */
747 }
748 lua_unlock(L);
749}
750
734 751
735LUA_API void lua_setglobal (lua_State *L, const char *name) { 752LUA_API void lua_setglobal (lua_State *L, const char *name) {
736 Table *reg = hvalue(&G(L)->l_registry); 753 Table *reg = hvalue(&G(L)->l_registry);
737 const TValue *gt; /* global table */
738 lua_lock(L); 754 lua_lock(L);
739 api_checknelems(L, 1); 755 auxsetstr(L, luaH_getint(reg, LUA_RIDX_GLOBALS), name);
740 gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
741 setsvalue2s(L, L->top, luaS_new(L, name));
742 api_incr_top(L);
743 luaV_settable(L, gt, L->top - 1, L->top - 2);
744 L->top -= 2; /* pop value and key */
745 lua_unlock(L);
746} 756}
747 757
748 758
@@ -758,27 +768,27 @@ LUA_API void lua_settable (lua_State *L, int idx) {
758 768
759 769
760LUA_API void lua_setfield (lua_State *L, int idx, const char *k) { 770LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
761 StkId t;
762 lua_lock(L); 771 lua_lock(L);
763 api_checknelems(L, 1); 772 auxsetstr(L, index2addr(L, idx), k);
764 t = index2addr(L, idx);
765 setsvalue2s(L, L->top, luaS_new(L, k));
766 api_incr_top(L);
767 luaV_settable(L, t, L->top - 1, L->top - 2);
768 L->top -= 2; /* pop value and key */
769 lua_unlock(L);
770} 773}
771 774
772 775
773LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) { 776LUA_API void lua_seti (lua_State *L, int idx, lua_Integer n) {
774 StkId t; 777 StkId t;
778 const TValue *aux;
775 lua_lock(L); 779 lua_lock(L);
776 api_checknelems(L, 1); 780 api_checknelems(L, 1);
777 t = index2addr(L, idx); 781 t = index2addr(L, idx);
778 setivalue(L->top, n); 782 if (luaV_fastset(L, t, n, aux, luaH_getint, L->top - 1)) {
779 api_incr_top(L); 783 setobj2t(L, cast(TValue *, aux), L->top - 1);
780 luaV_settable(L, t, L->top - 1, L->top - 2); 784 L->top--; /* pop value */
781 L->top -= 2; /* pop value and key */ 785 }
786 else {
787 setivalue(L->top, n);
788 api_incr_top(L);
789 luaV_finishset(L, t, L->top - 1, L->top - 2, aux);
790 L->top -= 2; /* pop value and key */
791 }
782 lua_unlock(L); 792 lua_unlock(L);
783} 793}
784 794
diff --git a/lvm.c b/lvm.c
index 4cb557f9..706acc43 100644
--- a/lvm.c
+++ b/lvm.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.c,v 2.247 2015/07/04 16:31:03 roberto Exp roberto $ 2** $Id: lvm.c,v 2.248 2015/07/20 18:24:50 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -184,40 +184,43 @@ void luaV_finishget (lua_State *L, const TValue *t, TValue *key, StkId val,
184** Main function for table assignment (invoking metamethods if needed). 184** Main function for table assignment (invoking metamethods if needed).
185** Compute 't[key] = val' 185** Compute 't[key] = val'
186*/ 186*/
187void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { 187void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
188 StkId val, const TValue *oldval) {
188 int loop; /* counter to avoid infinite loops */ 189 int loop; /* counter to avoid infinite loops */
189 for (loop = 0; loop < MAXTAGLOOP; loop++) { 190 for (loop = 0; loop < MAXTAGLOOP; loop++) {
190 const TValue *tm; 191 const TValue *tm;
191 if (ttistable(t)) { /* 't' is a table? */ 192 if (oldval != NULL) {
192 Table *h = hvalue(t); 193 lua_assert(ttistable(t) && ttisnil(oldval));
193 TValue *oldval = cast(TValue *, luaH_get(h, key)); 194 /* must check the metamethod */
194 /* if previous value is not nil, there must be a previous entry 195 if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL &&
195 in the table; a metamethod has no relevance */
196 if (!ttisnil(oldval) ||
197 /* previous value is nil; must check the metamethod */
198 ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
199 /* no metamethod; is there a previous entry in the table? */ 196 /* no metamethod; is there a previous entry in the table? */
200 (oldval != luaO_nilobject || 197 (oldval != luaO_nilobject ||
201 /* no previous entry; must create one. (The next test is 198 /* no previous entry; must create one. (The next test is
202 always true; we only need the assignment.) */ 199 always true; we only need the assignment.) */
203 (oldval = luaH_newkey(L, h, key), 1)))) { 200 (oldval = luaH_newkey(L, hvalue(t), key), 1))) {
204 /* no metamethod and (now) there is an entry with given key */ 201 /* no metamethod and (now) there is an entry with given key */
205 setobj2t(L, oldval, val); /* assign new value to that entry */ 202 setobj2t(L, cast(TValue *, oldval), val);
206 invalidateTMcache(h); 203 invalidateTMcache(hvalue(t));
207 luaC_barrierback(L, h, val); 204 luaC_barrierback(L, hvalue(t), val);
208 return; 205 return;
209 } 206 }
210 /* else will try the metamethod */ 207 /* else will try the metamethod */
211 } 208 }
212 else /* not a table; check metamethod */ 209 else { /* not a table; check metamethod */
213 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX))) 210 if (ttisnil(tm = luaT_gettmbyobj(L, t, TM_NEWINDEX)))
214 luaG_typeerror(L, t, "index"); 211 luaG_typeerror(L, t, "index");
212 }
215 /* try the metamethod */ 213 /* try the metamethod */
216 if (ttisfunction(tm)) { 214 if (ttisfunction(tm)) {
217 luaT_callTM(L, tm, t, key, val, 0); 215 luaT_callTM(L, tm, t, key, val, 0);
218 return; 216 return;
219 } 217 }
220 t = tm; /* else repeat assignment over 'tm' */ 218 t = tm; /* else repeat assignment over 'tm' */
219 if (luaV_fastset(L, t, key, oldval, luaH_get, val)) {
220 setobj2t(L, cast(TValue *, oldval), val);
221 return;
222 }
223 /* else loop */
221 } 224 }
222 luaG_runerror(L, "settable chain too long; possible loop"); 225 luaG_runerror(L, "settable chain too long; possible loop");
223} 226}
diff --git a/lvm.h b/lvm.h
index 9f7d028f..50927c70 100644
--- a/lvm.h
+++ b/lvm.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lvm.h,v 2.35 2015/02/20 14:27:53 roberto Exp roberto $ 2** $Id: lvm.h,v 2.36 2015/07/20 18:24:50 roberto Exp roberto $
3** Lua virtual machine 3** Lua virtual machine
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -70,6 +70,21 @@
70 else luaV_finishget(L,t,k,v,aux); } 70 else luaV_finishget(L,t,k,v,aux); }
71 71
72 72
73#define luaV_fastset(L,t,k,aux,f,v) \
74 (!ttistable(t) \
75 ? (aux = NULL, 0) \
76 : (aux = f(hvalue(t), k), \
77 ttisnil(aux) ? 0 \
78 : (invalidateTMcache(hvalue(t)), \
79 luaC_barrierback(L, hvalue(t), v), 1)))
80
81#define luaV_settable(L,t,k,v) { const TValue *aux; \
82 if (luaV_fastset(L,t,k,aux,luaH_get,v)) \
83 { setobj2t(L, cast(TValue *,aux), v); } \
84 else luaV_finishset(L,t,k,v,aux); }
85
86
87
73LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2); 88LUAI_FUNC int luaV_equalobj (lua_State *L, const TValue *t1, const TValue *t2);
74LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r); 89LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
75LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r); 90LUAI_FUNC int luaV_lessequal (lua_State *L, const TValue *l, const TValue *r);
@@ -77,8 +92,8 @@ LUAI_FUNC int luaV_tonumber_ (const TValue *obj, lua_Number *n);
77LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode); 92LUAI_FUNC int luaV_tointeger (const TValue *obj, lua_Integer *p, int mode);
78LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key, 93LUAI_FUNC void luaV_finishget (lua_State *L, const TValue *t, TValue *key,
79 StkId val, const TValue *tm); 94 StkId val, const TValue *tm);
80LUAI_FUNC void luaV_settable (lua_State *L, const TValue *t, TValue *key, 95LUAI_FUNC void luaV_finishset (lua_State *L, const TValue *t, TValue *key,
81 StkId val); 96 StkId val, const TValue *oldval);
82LUAI_FUNC void luaV_finishOp (lua_State *L); 97LUAI_FUNC void luaV_finishOp (lua_State *L);
83LUAI_FUNC void luaV_execute (lua_State *L); 98LUAI_FUNC void luaV_execute (lua_State *L);
84LUAI_FUNC void luaV_concat (lua_State *L, int total); 99LUAI_FUNC void luaV_concat (lua_State *L, int total);