@@ -123,12 +123,24 @@ static int prepclosingmethod (lua_State *L, TValue *obj, TValue *err) {
123123}
124124
125125
126+ /*
127+ ** Raise an error with message 'msg', inserting the name of the
128+ ** local variable at position 'level' in the stack.
129+ */
130+ static void varerror (lua_State * L , StkId level , const char * msg ) {
131+ int idx = cast_int (level - L -> ci -> func );
132+ const char * vname = luaG_findlocal (L , L -> ci , idx , NULL );
133+ if (vname == NULL ) vname = "?" ;
134+ luaG_runerror (L , msg , vname );
135+ }
136+
137+
126138/*
127139** Prepare and call a closing method. If status is OK, code is still
128140** inside the original protected call, and so any error will be handled
129- ** there. Otherwise, a previous error already activated original
141+ ** there. Otherwise, a previous error already activated the original
130142** protected call, and so the call to the closing method must be
131- ** protected here. (A status = CLOSEPROTECT behaves like a previous
143+ ** protected here. (A status == CLOSEPROTECT behaves like a previous
132144** error, to also run the closing method in protected mode).
133145** If status is OK, the call to the closing method will be pushed
134146** at the top of the stack. Otherwise, values are pushed after
@@ -140,12 +152,8 @@ static int callclosemth (lua_State *L, StkId level, int status) {
140152 if (likely (status == LUA_OK )) {
141153 if (prepclosingmethod (L , uv , & G (L )-> nilvalue )) /* something to call? */
142154 callclose (L , NULL ); /* call closing method */
143- else if (!ttisnil (uv )) { /* non-closable non-nil value? */
144- int idx = cast_int (level - L -> ci -> func );
145- const char * vname = luaG_findlocal (L , L -> ci , idx , NULL );
146- if (vname == NULL ) vname = "?" ;
147- luaG_runerror (L , "attempt to close non-closable variable '%s'" , vname );
148- }
155+ else if (!l_isfalse (uv )) /* non-closable non-false value? */
156+ varerror (L , level , "attempt to close non-closable variable '%s'" );
149157 }
150158 else { /* must close the object in protected mode */
151159 ptrdiff_t oldtop ;
@@ -170,9 +178,7 @@ static int callclosemth (lua_State *L, StkId level, int status) {
170178** (can raise a memory-allocation error)
171179*/
172180static void trynewtbcupval (lua_State * L , void * ud ) {
173- StkId level = cast (StkId , ud );
174- lua_assert (L -> openupval == NULL || uplevel (L -> openupval ) < level );
175- newupval (L , 1 , level , & L -> openupval );
181+ newupval (L , 1 , cast (StkId , ud ), & L -> openupval );
176182}
177183
178184
@@ -182,13 +188,22 @@ static void trynewtbcupval (lua_State *L, void *ud) {
182188** as there is no upvalue to call it later.
183189*/
184190void luaF_newtbcupval (lua_State * L , StkId level ) {
185- int status = luaD_rawrunprotected (L , trynewtbcupval , level );
186- if (unlikely (status != LUA_OK )) { /* memory error creating upvalue? */
187- lua_assert (status == LUA_ERRMEM );
188- luaD_seterrorobj (L , LUA_ERRMEM , level + 1 ); /* save error message */
189- if (prepclosingmethod (L , s2v (level ), s2v (level + 1 )))
191+ TValue * obj = s2v (level );
192+ lua_assert (L -> openupval == NULL || uplevel (L -> openupval ) < level );
193+ if (!l_isfalse (obj )) { /* false doesn't need to be closed */
194+ int status ;
195+ const TValue * tm = luaT_gettmbyobj (L , obj , TM_CLOSE );
196+ if (ttisnil (tm )) /* no metamethod? */
197+ varerror (L , level , "variable '%s' got a non-closable value" );
198+ status = luaD_rawrunprotected (L , trynewtbcupval , level );
199+ if (unlikely (status != LUA_OK )) { /* memory error creating upvalue? */
200+ lua_assert (status == LUA_ERRMEM );
201+ luaD_seterrorobj (L , LUA_ERRMEM , level + 1 ); /* save error message */
202+ /* next call must succeed, as object is closable */
203+ prepclosingmethod (L , s2v (level ), s2v (level + 1 ));
190204 callclose (L , NULL ); /* call closing method */
191- luaD_throw (L , LUA_ERRMEM ); /* throw memory error */
205+ luaD_throw (L , LUA_ERRMEM ); /* throw memory error */
206+ }
192207 }
193208}
194209
0 commit comments