diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-20 17:14:50 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-04-20 17:14:50 -0300 |
commit | ed720d09f37e642ba27603e8f2c8d2b68c39b84a (patch) | |
tree | 1b7a83976dcce1eae5dbf310329f29afd707035e /lapi.c | |
parent | 376e939ef62548ac64ab8f7b62051acd1ca452e3 (diff) | |
download | lua-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
Diffstat (limited to 'lapi.c')
-rw-r--r-- | lapi.c | 16 |
1 files changed, 10 insertions, 6 deletions
@@ -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 | ||
1076 | static const char *aux_upvalue (StkId fi, int n, TValue **val) { | 1076 | static 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) { | |||
1108 | LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | 1111 | LUA_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; |