diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-01-01 12:14:56 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2019-01-01 12:14:56 -0200 |
| commit | c6f7181e910b6b2ff1346b5486a31be87b1da5af (patch) | |
| tree | 92cc716487c83ecd9860444f23fd55ef65358cbb /lgc.c | |
| parent | 437a5b07d415e1a74160ddfd804017171d6cc5cb (diff) | |
| download | lua-c6f7181e910b6b2ff1346b5486a31be87b1da5af.tar.gz lua-c6f7181e910b6b2ff1346b5486a31be87b1da5af.tar.bz2 lua-c6f7181e910b6b2ff1346b5486a31be87b1da5af.zip | |
No more LUA_ERRGCMM errors
Errors in finalizers (__gc metamethods) are never propagated.
Instead, they generate a warning.
Diffstat (limited to 'lgc.c')
| -rw-r--r-- | lgc.c | 28 |
1 files changed, 13 insertions, 15 deletions
| @@ -824,7 +824,7 @@ static void dothecall (lua_State *L, void *ud) { | |||
| 824 | } | 824 | } |
| 825 | 825 | ||
| 826 | 826 | ||
| 827 | static void GCTM (lua_State *L, int propagateerrors) { | 827 | static void GCTM (lua_State *L) { |
| 828 | global_State *g = G(L); | 828 | global_State *g = G(L); |
| 829 | const TValue *tm; | 829 | const TValue *tm; |
| 830 | TValue v; | 830 | TValue v; |
| @@ -845,15 +845,13 @@ static void GCTM (lua_State *L, int propagateerrors) { | |||
| 845 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ | 845 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ |
| 846 | L->allowhook = oldah; /* restore hooks */ | 846 | L->allowhook = oldah; /* restore hooks */ |
| 847 | g->gcrunning = running; /* restore state */ | 847 | g->gcrunning = running; /* restore state */ |
| 848 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ | 848 | if (status != LUA_OK) { /* error while running __gc? */ |
| 849 | if (status == LUA_ERRRUN) { /* is there an error object? */ | 849 | const char *msg = (ttisstring(s2v(L->top - 1))) |
| 850 | const char *msg = (ttisstring(s2v(L->top - 1))) | 850 | ? svalue(s2v(L->top - 1)) |
| 851 | ? svalue(s2v(L->top - 1)) | 851 | : "error object is not a string"; |
| 852 | : "no message"; | 852 | luaE_warning(L, "error in __gc metamethod ("); |
| 853 | luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); | 853 | luaE_warning(L, msg); |
| 854 | status = LUA_ERRGCMM; /* error in __gc metamethod */ | 854 | luaE_warning(L, ")\n"); |
| 855 | } | ||
| 856 | luaD_throw(L, status); /* re-throw error */ | ||
| 857 | } | 855 | } |
| 858 | } | 856 | } |
| 859 | } | 857 | } |
| @@ -866,7 +864,7 @@ static int runafewfinalizers (lua_State *L, int n) { | |||
| 866 | global_State *g = G(L); | 864 | global_State *g = G(L); |
| 867 | int i; | 865 | int i; |
| 868 | for (i = 0; i < n && g->tobefnz; i++) | 866 | for (i = 0; i < n && g->tobefnz; i++) |
| 869 | GCTM(L, 1); /* call one finalizer */ | 867 | GCTM(L); /* call one finalizer */ |
| 870 | return i; | 868 | return i; |
| 871 | } | 869 | } |
| 872 | 870 | ||
| @@ -874,10 +872,10 @@ static int runafewfinalizers (lua_State *L, int n) { | |||
| 874 | /* | 872 | /* |
| 875 | ** call all pending finalizers | 873 | ** call all pending finalizers |
| 876 | */ | 874 | */ |
| 877 | static void callallpendingfinalizers (lua_State *L, int propagateerrors) { | 875 | static void callallpendingfinalizers (lua_State *L) { |
| 878 | global_State *g = G(L); | 876 | global_State *g = G(L); |
| 879 | while (g->tobefnz) | 877 | while (g->tobefnz) |
| 880 | GCTM(L, propagateerrors); | 878 | GCTM(L); |
| 881 | } | 879 | } |
| 882 | 880 | ||
| 883 | 881 | ||
| @@ -1124,7 +1122,7 @@ static void finishgencycle (lua_State *L, global_State *g) { | |||
| 1124 | checkSizes(L, g); | 1122 | checkSizes(L, g); |
| 1125 | g->gcstate = GCSpropagate; /* skip restart */ | 1123 | g->gcstate = GCSpropagate; /* skip restart */ |
| 1126 | if (!g->gcemergency) | 1124 | if (!g->gcemergency) |
| 1127 | callallpendingfinalizers(L, 1); | 1125 | callallpendingfinalizers(L); |
| 1128 | } | 1126 | } |
| 1129 | 1127 | ||
| 1130 | 1128 | ||
| @@ -1334,7 +1332,7 @@ void luaC_freeallobjects (lua_State *L) { | |||
| 1334 | luaC_changemode(L, KGC_INC); | 1332 | luaC_changemode(L, KGC_INC); |
| 1335 | separatetobefnz(g, 1); /* separate all objects with finalizers */ | 1333 | separatetobefnz(g, 1); /* separate all objects with finalizers */ |
| 1336 | lua_assert(g->finobj == NULL); | 1334 | lua_assert(g->finobj == NULL); |
| 1337 | callallpendingfinalizers(L, 0); | 1335 | callallpendingfinalizers(L); |
| 1338 | deletelist(L, g->allgc, obj2gco(g->mainthread)); | 1336 | deletelist(L, g->allgc, obj2gco(g->mainthread)); |
| 1339 | deletelist(L, g->finobj, NULL); | 1337 | deletelist(L, g->finobj, NULL); |
| 1340 | deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ | 1338 | deletelist(L, g->fixedgc, NULL); /* collect fixed objects */ |
