aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-04-20 17:14:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2010-04-20 17:14:50 -0300
commited720d09f37e642ba27603e8f2c8d2b68c39b84a (patch)
tree1b7a83976dcce1eae5dbf310329f29afd707035e
parent376e939ef62548ac64ab8f7b62051acd1ca452e3 (diff)
downloadlua-ed720d09f37e642ba27603e8f2c8d2b68c39b84a.tar.gz
lua-ed720d09f37e642ba27603e8f2c8d2b68c39b84a.tar.bz2
lua-ed720d09f37e642ba27603e8f2c8d2b68c39b84a.zip
upvalue barriers for Lua functions must act on the upvalue itself,
not on its closure
-rw-r--r--lapi.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/lapi.c b/lapi.c
index 39934790..e29db1c3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lapi.c,v 2.122 2010/04/18 13:22:48 roberto Exp roberto $ 2** $Id: lapi.c,v 2.123 2010/04/19 16:33:19 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*/
@@ -874,7 +874,7 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
874 const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS); 874 const TValue *gt = luaH_getint(reg, LUA_RIDX_GLOBALS);
875 /* set global table as 1st upvalue of 'f' (may be _ENV) */ 875 /* set global table as 1st upvalue of 'f' (may be _ENV) */
876 setobj(L, f->l.upvals[0]->v, gt); 876 setobj(L, f->l.upvals[0]->v, gt);
877 luaC_barrier(L, f, gt); 877 luaC_barrier(L, f->l.upvals[0], gt);
878 } 878 }
879 } 879 }
880 lua_unlock(L); 880 lua_unlock(L);
@@ -1073,19 +1073,22 @@ LUA_API void *lua_newuserdata (lua_State *L, size_t size) {
1073 1073
1074 1074
1075 1075
1076static const char *aux_upvalue (StkId fi, int n, TValue **val) { 1076static const char *aux_upvalue (StkId fi, int n, TValue **val,
1077 GCObject **owner) {
1077 Closure *f; 1078 Closure *f;
1078 if (!ttisclosure(fi)) return NULL; 1079 if (!ttisclosure(fi)) return NULL;
1079 f = clvalue(fi); 1080 f = clvalue(fi);
1080 if (f->c.isC) { 1081 if (f->c.isC) {
1081 if (!(1 <= n && n <= f->c.nupvalues)) return NULL; 1082 if (!(1 <= n && n <= f->c.nupvalues)) return NULL;
1082 *val = &f->c.upvalue[n-1]; 1083 *val = &f->c.upvalue[n-1];
1084 if (owner) *owner = obj2gco(f);
1083 return ""; 1085 return "";
1084 } 1086 }
1085 else { 1087 else {
1086 Proto *p = f->l.p; 1088 Proto *p = f->l.p;
1087 if (!(1 <= n && n <= p->sizeupvalues)) return NULL; 1089 if (!(1 <= n && n <= p->sizeupvalues)) return NULL;
1088 *val = f->l.upvals[n-1]->v; 1090 *val = f->l.upvals[n-1]->v;
1091 if (owner) *owner = obj2gco(f->l.upvals[n - 1]);
1089 return getstr(p->upvalues[n-1].name); 1092 return getstr(p->upvalues[n-1].name);
1090 } 1093 }
1091} 1094}
@@ -1095,7 +1098,7 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1095 const char *name; 1098 const char *name;
1096 TValue *val; 1099 TValue *val;
1097 lua_lock(L); 1100 lua_lock(L);
1098 name = aux_upvalue(index2addr(L, funcindex), n, &val); 1101 name = aux_upvalue(index2addr(L, funcindex), n, &val, NULL);
1099 if (name) { 1102 if (name) {
1100 setobj2s(L, L->top, val); 1103 setobj2s(L, L->top, val);
1101 api_incr_top(L); 1104 api_incr_top(L);
@@ -1108,15 +1111,16 @@ LUA_API const char *lua_getupvalue (lua_State *L, int funcindex, int n) {
1108LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { 1111LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) {
1109 const char *name; 1112 const char *name;
1110 TValue *val; 1113 TValue *val;
1114 GCObject *owner;
1111 StkId fi; 1115 StkId fi;
1112 lua_lock(L); 1116 lua_lock(L);
1113 fi = index2addr(L, funcindex); 1117 fi = index2addr(L, funcindex);
1114 api_checknelems(L, 1); 1118 api_checknelems(L, 1);
1115 name = aux_upvalue(fi, n, &val); 1119 name = aux_upvalue(fi, n, &val, &owner);
1116 if (name) { 1120 if (name) {
1117 L->top--; 1121 L->top--;
1118 setobj(L, val, L->top); 1122 setobj(L, val, L->top);
1119 luaC_barrier(L, clvalue(fi), L->top); 1123 luaC_barrier(L, owner, L->top);
1120 } 1124 }
1121 lua_unlock(L); 1125 lua_unlock(L);
1122 return name; 1126 return name;