aboutsummaryrefslogtreecommitdiff
path: root/lfunc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-02-28 10:10:27 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-02-28 10:10:27 -0300
commit127a8e80fe0d74efd26994b3877cdc77b712ea56 (patch)
tree12b8b3be0660884f4a1075af37e0f58cbd43a3d3 /lfunc.c
parentf9e35627ed26dff4114a1d01ff113d8b4cc91ab5 (diff)
downloadlua-127a8e80fe0d74efd26994b3877cdc77b712ea56.tar.gz
lua-127a8e80fe0d74efd26994b3877cdc77b712ea56.tar.bz2
lua-127a8e80fe0d74efd26994b3877cdc77b712ea56.zip
'__close' gets no error object if there is no error
Instead of receiving nil as a second argument, __close metamethods are called with just one argument when there are no errors.
Diffstat (limited to 'lfunc.c')
-rw-r--r--lfunc.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/lfunc.c b/lfunc.c
index d6853ff8..c62a5d23 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -100,21 +100,23 @@ UpVal *luaF_findupval (lua_State *L, StkId level) {
100 100
101 101
102/* 102/*
103** Call closing method for object 'obj' with error message 'err'. The 103** Call closing method for object 'obj' with error object 'err'. The
104** boolean 'yy' controls whether the call is yieldable. 104** boolean 'yy' controls whether the call is yieldable.
105** (This function assumes EXTRA_STACK.) 105** (This function assumes EXTRA_STACK.)
106*/ 106*/
107static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) { 107static void callclosemethod (lua_State *L, TValue *obj, TValue *err, int yy) {
108 StkId top = L->top.p; 108 StkId top = L->top.p;
109 StkId func = top;
109 const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE); 110 const TValue *tm = luaT_gettmbyobj(L, obj, TM_CLOSE);
110 setobj2s(L, top, tm); /* will call metamethod... */ 111 setobj2s(L, top++, tm); /* will call metamethod... */
111 setobj2s(L, top + 1, obj); /* with 'self' as the 1st argument */ 112 setobj2s(L, top++, obj); /* with 'self' as the 1st argument */
112 setobj2s(L, top + 2, err); /* and error msg. as 2nd argument */ 113 if (err != NULL) /* if there was an error... */
113 L->top.p = top + 3; /* add function and arguments */ 114 setobj2s(L, top++, err); /* then error object will be 2nd argument */
115 L->top.p = top; /* add function and arguments */
114 if (yy) 116 if (yy)
115 luaD_call(L, top, 0); 117 luaD_call(L, func, 0);
116 else 118 else
117 luaD_callnoyield(L, top, 0); 119 luaD_callnoyield(L, func, 0);
118} 120}
119 121
120 122
@@ -144,11 +146,17 @@ static void prepcallclosemth (lua_State *L, StkId level, TStatus status,
144 int yy) { 146 int yy) {
145 TValue *uv = s2v(level); /* value being closed */ 147 TValue *uv = s2v(level); /* value being closed */
146 TValue *errobj; 148 TValue *errobj;
147 if (status == CLOSEKTOP) 149 switch (status) {
148 errobj = &G(L)->nilvalue; /* error object is nil */ 150 case LUA_OK:
149 else { /* 'luaD_seterrorobj' will set top to level + 2 */ 151 L->top.p = level + 1; /* call will be at this level */
150 errobj = s2v(level + 1); /* error object goes after 'uv' */ 152 /* FALLTHROUGH */
151 luaD_seterrorobj(L, status, level + 1); /* set error object */ 153 case CLOSEKTOP: /* don't need to change top */
154 errobj = NULL; /* no error object */
155 break;
156 default: /* 'luaD_seterrorobj' will set top to level + 2 */
157 errobj = s2v(level + 1); /* error object goes after 'uv' */
158 luaD_seterrorobj(L, status, level + 1); /* set error object */
159 break;
152 } 160 }
153 callclosemethod(L, uv, errobj, yy); 161 callclosemethod(L, uv, errobj, yy);
154} 162}