diff options
author | Li Jin <dragon-fly@qq.com> | 2020-10-22 16:02:39 +0800 |
---|---|---|
committer | Li Jin <dragon-fly@qq.com> | 2020-10-22 16:02:39 +0800 |
commit | a51a728d847e790329e41c75928a81630200b63f (patch) | |
tree | 8cc8e93a7863649499537366acecb41525022a57 | |
parent | f6e603cc5bef133e5e368a81f677bea92bc405b5 (diff) | |
download | yuescript-a51a728d847e790329e41c75928a81630200b63f.tar.gz yuescript-a51a728d847e790329e41c75928a81630200b63f.tar.bz2 yuescript-a51a728d847e790329e41c75928a81630200b63f.zip |
update Lua, fix cmakelists.txt.
-rw-r--r-- | CMakeLists.txt | 8 | ||||
-rw-r--r-- | src/lua/lapi.c | 19 | ||||
-rw-r--r-- | src/lua/lctype.h | 14 | ||||
-rw-r--r-- | src/lua/ldblib.c | 29 | ||||
-rw-r--r-- | src/lua/ldo.c | 145 | ||||
-rw-r--r-- | src/lua/ldo.h | 1 | ||||
-rw-r--r-- | src/lua/lfunc.c | 2 | ||||
-rw-r--r-- | src/lua/lgc.c | 52 | ||||
-rw-r--r-- | src/lua/llex.c | 1 | ||||
-rw-r--r-- | src/lua/llex.h | 8 | ||||
-rw-r--r-- | src/lua/llimits.h | 13 | ||||
-rw-r--r-- | src/lua/lobject.h | 18 | ||||
-rw-r--r-- | src/lua/lopcodes.h | 4 | ||||
-rw-r--r-- | src/lua/lparser.c | 8 | ||||
-rw-r--r-- | src/lua/lstate.c | 96 | ||||
-rw-r--r-- | src/lua/lstate.h | 102 | ||||
-rw-r--r-- | src/lua/lstring.c | 20 | ||||
-rw-r--r-- | src/lua/lstring.h | 3 | ||||
-rw-r--r-- | src/lua/lstrlib.c | 19 | ||||
-rw-r--r-- | src/lua/ltable.c | 27 | ||||
-rw-r--r-- | src/lua/lua.h | 2 | ||||
-rw-r--r-- | src/lua/luaconf.h | 15 | ||||
-rw-r--r-- | src/lua/lvm.c | 75 | ||||
-rw-r--r-- | src/lua/makefile | 3 |
24 files changed, 349 insertions, 335 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index fc58572..d865000 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt | |||
@@ -33,4 +33,10 @@ add_library( moonp MODULE src/MoonP/ast.cpp src/MoonP/parser.cpp src/MoonP/moon_ | |||
33 | set_target_properties( moonp PROPERTIES PREFIX "") | 33 | set_target_properties( moonp PROPERTIES PREFIX "") |
34 | target_link_libraries( moonp ${LUA_LIBRARIES} ) | 34 | target_link_libraries( moonp ${LUA_LIBRARIES} ) |
35 | 35 | ||
36 | install(CODE "") | 36 | add_custom_command(TARGET moonp |
37 | POST_BUILD | ||
38 | COMMAND make release | ||
39 | WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) | ||
40 | |||
41 | install(PROGRAMS bin/release/moonp DESTINATION bin) | ||
42 | |||
diff --git a/src/lua/lapi.c b/src/lua/lapi.c index 9048245..c824da2 100644 --- a/src/lua/lapi.c +++ b/src/lua/lapi.c | |||
@@ -1383,13 +1383,16 @@ LUA_API const char *lua_setupvalue (lua_State *L, int funcindex, int n) { | |||
1383 | 1383 | ||
1384 | 1384 | ||
1385 | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { | 1385 | static UpVal **getupvalref (lua_State *L, int fidx, int n, LClosure **pf) { |
1386 | static const UpVal *const nullup = NULL; | ||
1386 | LClosure *f; | 1387 | LClosure *f; |
1387 | TValue *fi = index2value(L, fidx); | 1388 | TValue *fi = index2value(L, fidx); |
1388 | api_check(L, ttisLclosure(fi), "Lua function expected"); | 1389 | api_check(L, ttisLclosure(fi), "Lua function expected"); |
1389 | f = clLvalue(fi); | 1390 | f = clLvalue(fi); |
1390 | api_check(L, (1 <= n && n <= f->p->sizeupvalues), "invalid upvalue index"); | ||
1391 | if (pf) *pf = f; | 1391 | if (pf) *pf = f; |
1392 | return &f->upvals[n - 1]; /* get its upvalue pointer */ | 1392 | if (1 <= n && n <= f->p->sizeupvalues) |
1393 | return &f->upvals[n - 1]; /* get its upvalue pointer */ | ||
1394 | else | ||
1395 | return (UpVal**)&nullup; | ||
1393 | } | 1396 | } |
1394 | 1397 | ||
1395 | 1398 | ||
@@ -1401,11 +1404,14 @@ LUA_API void *lua_upvalueid (lua_State *L, int fidx, int n) { | |||
1401 | } | 1404 | } |
1402 | case LUA_VCCL: { /* C closure */ | 1405 | case LUA_VCCL: { /* C closure */ |
1403 | CClosure *f = clCvalue(fi); | 1406 | CClosure *f = clCvalue(fi); |
1404 | api_check(L, 1 <= n && n <= f->nupvalues, "invalid upvalue index"); | 1407 | if (1 <= n && n <= f->nupvalues) |
1405 | return &f->upvalue[n - 1]; | 1408 | return &f->upvalue[n - 1]; |
1406 | } | 1409 | /* else */ |
1410 | } /* FALLTHROUGH */ | ||
1411 | case LUA_VLCF: | ||
1412 | return NULL; /* light C functions have no upvalues */ | ||
1407 | default: { | 1413 | default: { |
1408 | api_check(L, 0, "closure expected"); | 1414 | api_check(L, 0, "function expected"); |
1409 | return NULL; | 1415 | return NULL; |
1410 | } | 1416 | } |
1411 | } | 1417 | } |
@@ -1417,6 +1423,7 @@ LUA_API void lua_upvaluejoin (lua_State *L, int fidx1, int n1, | |||
1417 | LClosure *f1; | 1423 | LClosure *f1; |
1418 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); | 1424 | UpVal **up1 = getupvalref(L, fidx1, n1, &f1); |
1419 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); | 1425 | UpVal **up2 = getupvalref(L, fidx2, n2, NULL); |
1426 | api_check(L, *up1 != NULL && *up2 != NULL, "invalid upvalue index"); | ||
1420 | *up1 = *up2; | 1427 | *up1 = *up2; |
1421 | luaC_objbarrier(L, f1, *up1); | 1428 | luaC_objbarrier(L, f1, *up1); |
1422 | } | 1429 | } |
diff --git a/src/lua/lctype.h b/src/lua/lctype.h index cbff4d7..864e190 100644 --- a/src/lua/lctype.h +++ b/src/lua/lctype.h | |||
@@ -13,7 +13,7 @@ | |||
13 | /* | 13 | /* |
14 | ** WARNING: the functions defined here do not necessarily correspond | 14 | ** WARNING: the functions defined here do not necessarily correspond |
15 | ** to the similar functions in the standard C ctype.h. They are | 15 | ** to the similar functions in the standard C ctype.h. They are |
16 | ** optimized for the specific needs of Lua | 16 | ** optimized for the specific needs of Lua. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #if !defined(LUA_USE_CTYPE) | 19 | #if !defined(LUA_USE_CTYPE) |
@@ -61,13 +61,19 @@ | |||
61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) | 61 | #define lisprint(c) testprop(c, MASK(PRINTBIT)) |
62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) | 62 | #define lisxdigit(c) testprop(c, MASK(XDIGITBIT)) |
63 | 63 | ||
64 | |||
64 | /* | 65 | /* |
65 | ** this 'ltolower' only works for alphabetic characters | 66 | ** In ASCII, this 'ltolower' is correct for alphabetic characters and |
67 | ** for '.'. That is enough for Lua needs. ('check_exp' ensures that | ||
68 | ** the character either is an upper-case letter or is unchanged by | ||
69 | ** the transformation, which holds for lower-case letters and '.'.) | ||
66 | */ | 70 | */ |
67 | #define ltolower(c) ((c) | ('A' ^ 'a')) | 71 | #define ltolower(c) \ |
72 | check_exp(('A' <= (c) && (c) <= 'Z') || (c) == ((c) | ('A' ^ 'a')), \ | ||
73 | (c) | ('A' ^ 'a')) | ||
68 | 74 | ||
69 | 75 | ||
70 | /* two more entries for 0 and -1 (EOZ) */ | 76 | /* one entry for each character and for -1 (EOZ) */ |
71 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) | 77 | LUAI_DDEC(const lu_byte luai_ctype_[UCHAR_MAX + 2];) |
72 | 78 | ||
73 | 79 | ||
diff --git a/src/lua/ldblib.c b/src/lua/ldblib.c index 59eb8f0..5a326ad 100644 --- a/src/lua/ldblib.c +++ b/src/lua/ldblib.c | |||
@@ -281,25 +281,33 @@ static int db_setupvalue (lua_State *L) { | |||
281 | ** Check whether a given upvalue from a given closure exists and | 281 | ** Check whether a given upvalue from a given closure exists and |
282 | ** returns its index | 282 | ** returns its index |
283 | */ | 283 | */ |
284 | static int checkupval (lua_State *L, int argf, int argnup) { | 284 | static void *checkupval (lua_State *L, int argf, int argnup, int *pnup) { |
285 | void *id; | ||
285 | int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ | 286 | int nup = (int)luaL_checkinteger(L, argnup); /* upvalue index */ |
286 | luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ | 287 | luaL_checktype(L, argf, LUA_TFUNCTION); /* closure */ |
287 | luaL_argcheck(L, (lua_getupvalue(L, argf, nup) != NULL), argnup, | 288 | id = lua_upvalueid(L, argf, nup); |
288 | "invalid upvalue index"); | 289 | if (pnup) { |
289 | return nup; | 290 | luaL_argcheck(L, id != NULL, argnup, "invalid upvalue index"); |
291 | *pnup = nup; | ||
292 | } | ||
293 | return id; | ||
290 | } | 294 | } |
291 | 295 | ||
292 | 296 | ||
293 | static int db_upvalueid (lua_State *L) { | 297 | static int db_upvalueid (lua_State *L) { |
294 | int n = checkupval(L, 1, 2); | 298 | void *id = checkupval(L, 1, 2, NULL); |
295 | lua_pushlightuserdata(L, lua_upvalueid(L, 1, n)); | 299 | if (id != NULL) |
300 | lua_pushlightuserdata(L, id); | ||
301 | else | ||
302 | luaL_pushfail(L); | ||
296 | return 1; | 303 | return 1; |
297 | } | 304 | } |
298 | 305 | ||
299 | 306 | ||
300 | static int db_upvaluejoin (lua_State *L) { | 307 | static int db_upvaluejoin (lua_State *L) { |
301 | int n1 = checkupval(L, 1, 2); | 308 | int n1, n2; |
302 | int n2 = checkupval(L, 3, 4); | 309 | checkupval(L, 1, 2, &n1); |
310 | checkupval(L, 3, 4, &n2); | ||
303 | luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); | 311 | luaL_argcheck(L, !lua_iscfunction(L, 1), 1, "Lua function expected"); |
304 | luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); | 312 | luaL_argcheck(L, !lua_iscfunction(L, 3), 3, "Lua function expected"); |
305 | lua_upvaluejoin(L, 1, n1, 3, n2); | 313 | lua_upvaluejoin(L, 1, n1, 3, n2); |
@@ -440,10 +448,7 @@ static int db_traceback (lua_State *L) { | |||
440 | static int db_setcstacklimit (lua_State *L) { | 448 | static int db_setcstacklimit (lua_State *L) { |
441 | int limit = (int)luaL_checkinteger(L, 1); | 449 | int limit = (int)luaL_checkinteger(L, 1); |
442 | int res = lua_setcstacklimit(L, limit); | 450 | int res = lua_setcstacklimit(L, limit); |
443 | if (res == 0) | 451 | lua_pushinteger(L, res); |
444 | lua_pushboolean(L, 0); | ||
445 | else | ||
446 | lua_pushinteger(L, res); | ||
447 | return 1; | 452 | return 1; |
448 | } | 453 | } |
449 | 454 | ||
diff --git a/src/lua/ldo.c b/src/lua/ldo.c index 5473815..5729b19 100644 --- a/src/lua/ldo.c +++ b/src/lua/ldo.c | |||
@@ -139,8 +139,7 @@ l_noret luaD_throw (lua_State *L, int errcode) { | |||
139 | 139 | ||
140 | 140 | ||
141 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | 141 | int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { |
142 | global_State *g = G(L); | 142 | l_uint32 oldnCcalls = L->nCcalls; |
143 | l_uint32 oldnCcalls = g->Cstacklimit - (L->nCcalls + L->nci); | ||
144 | struct lua_longjmp lj; | 143 | struct lua_longjmp lj; |
145 | lj.status = LUA_OK; | 144 | lj.status = LUA_OK; |
146 | lj.previous = L->errorJmp; /* chain new error handler */ | 145 | lj.previous = L->errorJmp; /* chain new error handler */ |
@@ -149,7 +148,7 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
149 | (*f)(L, ud); | 148 | (*f)(L, ud); |
150 | ); | 149 | ); |
151 | L->errorJmp = lj.previous; /* restore old error handler */ | 150 | L->errorJmp = lj.previous; /* restore old error handler */ |
152 | L->nCcalls = g->Cstacklimit - oldnCcalls - L->nci; | 151 | L->nCcalls = oldnCcalls; |
153 | return lj.status; | 152 | return lj.status; |
154 | } | 153 | } |
155 | 154 | ||
@@ -183,10 +182,10 @@ static void correctstack (lua_State *L, StkId oldstack, StkId newstack) { | |||
183 | 182 | ||
184 | 183 | ||
185 | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | 184 | int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { |
186 | int lim = L->stacksize; | 185 | int lim = stacksize(L); |
187 | StkId newstack = luaM_reallocvector(L, L->stack, lim, newsize, StackValue); | 186 | StkId newstack = luaM_reallocvector(L, L->stack, |
187 | lim + EXTRA_STACK, newsize + EXTRA_STACK, StackValue); | ||
188 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); | 188 | lua_assert(newsize <= LUAI_MAXSTACK || newsize == ERRORSTACKSIZE); |
189 | lua_assert(L->stack_last - L->stack == L->stacksize - EXTRA_STACK); | ||
190 | if (unlikely(newstack == NULL)) { /* reallocation failed? */ | 189 | if (unlikely(newstack == NULL)) { /* reallocation failed? */ |
191 | if (raiseerror) | 190 | if (raiseerror) |
192 | luaM_error(L); | 191 | luaM_error(L); |
@@ -196,8 +195,7 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | |||
196 | setnilvalue(s2v(newstack + lim)); /* erase new segment */ | 195 | setnilvalue(s2v(newstack + lim)); /* erase new segment */ |
197 | correctstack(L, L->stack, newstack); | 196 | correctstack(L, L->stack, newstack); |
198 | L->stack = newstack; | 197 | L->stack = newstack; |
199 | L->stacksize = newsize; | 198 | L->stack_last = L->stack + newsize; |
200 | L->stack_last = L->stack + newsize - EXTRA_STACK; | ||
201 | return 1; | 199 | return 1; |
202 | } | 200 | } |
203 | 201 | ||
@@ -207,51 +205,73 @@ int luaD_reallocstack (lua_State *L, int newsize, int raiseerror) { | |||
207 | ** is true, raises any error; otherwise, return 0 in case of errors. | 205 | ** is true, raises any error; otherwise, return 0 in case of errors. |
208 | */ | 206 | */ |
209 | int luaD_growstack (lua_State *L, int n, int raiseerror) { | 207 | int luaD_growstack (lua_State *L, int n, int raiseerror) { |
210 | int size = L->stacksize; | 208 | int size = stacksize(L); |
211 | int newsize = 2 * size; /* tentative new size */ | 209 | if (unlikely(size > LUAI_MAXSTACK)) { |
212 | if (unlikely(size > LUAI_MAXSTACK)) { /* need more space after extra size? */ | 210 | /* if stack is larger than maximum, thread is already using the |
211 | extra space reserved for errors, that is, thread is handling | ||
212 | a stack error; cannot grow further than that. */ | ||
213 | lua_assert(stacksize(L) == ERRORSTACKSIZE); | ||
213 | if (raiseerror) | 214 | if (raiseerror) |
214 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ | 215 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ |
215 | else return 0; | 216 | return 0; /* if not 'raiseerror', just signal it */ |
216 | } | 217 | } |
217 | else { | 218 | else { |
218 | int needed = cast_int(L->top - L->stack) + n + EXTRA_STACK; | 219 | int newsize = 2 * size; /* tentative new size */ |
220 | int needed = cast_int(L->top - L->stack) + n; | ||
219 | if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ | 221 | if (newsize > LUAI_MAXSTACK) /* cannot cross the limit */ |
220 | newsize = LUAI_MAXSTACK; | 222 | newsize = LUAI_MAXSTACK; |
221 | if (newsize < needed) /* but must respect what was asked for */ | 223 | if (newsize < needed) /* but must respect what was asked for */ |
222 | newsize = needed; | 224 | newsize = needed; |
223 | if (unlikely(newsize > LUAI_MAXSTACK)) { /* stack overflow? */ | 225 | if (likely(newsize <= LUAI_MAXSTACK)) |
226 | return luaD_reallocstack(L, newsize, raiseerror); | ||
227 | else { /* stack overflow */ | ||
224 | /* add extra size to be able to handle the error message */ | 228 | /* add extra size to be able to handle the error message */ |
225 | luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); | 229 | luaD_reallocstack(L, ERRORSTACKSIZE, raiseerror); |
226 | if (raiseerror) | 230 | if (raiseerror) |
227 | luaG_runerror(L, "stack overflow"); | 231 | luaG_runerror(L, "stack overflow"); |
228 | else return 0; | 232 | return 0; |
229 | } | 233 | } |
230 | } /* else no errors */ | 234 | } |
231 | return luaD_reallocstack(L, newsize, raiseerror); | ||
232 | } | 235 | } |
233 | 236 | ||
234 | 237 | ||
235 | static int stackinuse (lua_State *L) { | 238 | static int stackinuse (lua_State *L) { |
236 | CallInfo *ci; | 239 | CallInfo *ci; |
240 | int res; | ||
237 | StkId lim = L->top; | 241 | StkId lim = L->top; |
238 | for (ci = L->ci; ci != NULL; ci = ci->previous) { | 242 | for (ci = L->ci; ci != NULL; ci = ci->previous) { |
239 | if (lim < ci->top) lim = ci->top; | 243 | if (lim < ci->top) lim = ci->top; |
240 | } | 244 | } |
241 | lua_assert(lim <= L->stack_last); | 245 | lua_assert(lim <= L->stack_last); |
242 | return cast_int(lim - L->stack) + 1; /* part of stack in use */ | 246 | res = cast_int(lim - L->stack) + 1; /* part of stack in use */ |
247 | if (res < LUA_MINSTACK) | ||
248 | res = LUA_MINSTACK; /* ensure a minimum size */ | ||
249 | return res; | ||
243 | } | 250 | } |
244 | 251 | ||
245 | 252 | ||
253 | /* | ||
254 | ** If stack size is more than 3 times the current use, reduce that size | ||
255 | ** to twice the current use. (So, the final stack size is at most 2/3 the | ||
256 | ** previous size, and half of its entries are empty.) | ||
257 | ** As a particular case, if stack was handling a stack overflow and now | ||
258 | ** it is not, 'max' (limited by LUAI_MAXSTACK) will be smaller than | ||
259 | ** stacksize (equal to ERRORSTACKSIZE in this case), and so the stack | ||
260 | ** will be reduced to a "regular" size. | ||
261 | */ | ||
246 | void luaD_shrinkstack (lua_State *L) { | 262 | void luaD_shrinkstack (lua_State *L) { |
247 | int inuse = stackinuse(L); | 263 | int inuse = stackinuse(L); |
248 | int goodsize = inuse + BASIC_STACK_SIZE; | 264 | int nsize = inuse * 2; /* proposed new size */ |
249 | if (goodsize > LUAI_MAXSTACK) | 265 | int max = inuse * 3; /* maximum "reasonable" size */ |
250 | goodsize = LUAI_MAXSTACK; /* respect stack limit */ | 266 | if (max > LUAI_MAXSTACK) { |
267 | max = LUAI_MAXSTACK; /* respect stack limit */ | ||
268 | if (nsize > LUAI_MAXSTACK) | ||
269 | nsize = LUAI_MAXSTACK; | ||
270 | } | ||
251 | /* if thread is currently not handling a stack overflow and its | 271 | /* if thread is currently not handling a stack overflow and its |
252 | good size is smaller than current size, shrink its stack */ | 272 | size is larger than maximum "reasonable" size, shrink it */ |
253 | if (inuse <= (LUAI_MAXSTACK - EXTRA_STACK) && goodsize < L->stacksize) | 273 | if (inuse <= LUAI_MAXSTACK && stacksize(L) > max) |
254 | luaD_reallocstack(L, goodsize, 0); /* ok if that fails */ | 274 | luaD_reallocstack(L, nsize, 0); /* ok if that fails */ |
255 | else /* don't change stack */ | 275 | else /* don't change stack */ |
256 | condmovestack(L,{},{}); /* (change only for debugging) */ | 276 | condmovestack(L,{},{}); /* (change only for debugging) */ |
257 | luaE_shrinkCI(L); /* shrink CI list */ | 277 | luaE_shrinkCI(L); /* shrink CI list */ |
@@ -348,7 +368,7 @@ static StkId rethook (lua_State *L, CallInfo *ci, StkId firstres, int nres) { | |||
348 | 368 | ||
349 | /* | 369 | /* |
350 | ** Check whether 'func' has a '__call' metafield. If so, put it in the | 370 | ** Check whether 'func' has a '__call' metafield. If so, put it in the |
351 | ** stack, below original 'func', so that 'luaD_call' can call it. Raise | 371 | ** stack, below original 'func', so that 'luaD_precall' can call it. Raise |
352 | ** an error if there is no '__call' metafield. | 372 | ** an error if there is no '__call' metafield. |
353 | */ | 373 | */ |
354 | void luaD_tryfuncTM (lua_State *L, StkId func) { | 374 | void luaD_tryfuncTM (lua_State *L, StkId func) { |
@@ -449,12 +469,14 @@ void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int narg1) { | |||
449 | 469 | ||
450 | 470 | ||
451 | /* | 471 | /* |
452 | ** Call a function (C or Lua). The function to be called is at *func. | 472 | ** Prepares the call to a function (C or Lua). For C functions, also do |
453 | ** The arguments are on the stack, right after the function. | 473 | ** the call. The function to be called is at '*func'. The arguments |
454 | ** When returns, all the results are on the stack, starting at the original | 474 | ** are on the stack, right after the function. Returns the CallInfo |
455 | ** function position. | 475 | ** to be executed, if it was a Lua function. Otherwise (a C function) |
476 | ** returns NULL, with all the results on the stack, starting at the | ||
477 | ** original function position. | ||
456 | */ | 478 | */ |
457 | void luaD_call (lua_State *L, StkId func, int nresults) { | 479 | CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) { |
458 | lua_CFunction f; | 480 | lua_CFunction f; |
459 | retry: | 481 | retry: |
460 | switch (ttypetag(s2v(func))) { | 482 | switch (ttypetag(s2v(func))) { |
@@ -482,7 +504,7 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
482 | lua_lock(L); | 504 | lua_lock(L); |
483 | api_checknelems(L, n); | 505 | api_checknelems(L, n); |
484 | luaD_poscall(L, ci, n); | 506 | luaD_poscall(L, ci, n); |
485 | break; | 507 | return NULL; |
486 | } | 508 | } |
487 | case LUA_VLCL: { /* Lua function */ | 509 | case LUA_VLCL: { /* Lua function */ |
488 | CallInfo *ci; | 510 | CallInfo *ci; |
@@ -494,15 +516,13 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
494 | L->ci = ci = next_ci(L); | 516 | L->ci = ci = next_ci(L); |
495 | ci->nresults = nresults; | 517 | ci->nresults = nresults; |
496 | ci->u.l.savedpc = p->code; /* starting point */ | 518 | ci->u.l.savedpc = p->code; /* starting point */ |
497 | ci->callstatus = 0; | ||
498 | ci->top = func + 1 + fsize; | 519 | ci->top = func + 1 + fsize; |
499 | ci->func = func; | 520 | ci->func = func; |
500 | L->ci = ci; | 521 | L->ci = ci; |
501 | for (; narg < nfixparams; narg++) | 522 | for (; narg < nfixparams; narg++) |
502 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ | 523 | setnilvalue(s2v(L->top++)); /* complete missing arguments */ |
503 | lua_assert(ci->top <= L->stack_last); | 524 | lua_assert(ci->top <= L->stack_last); |
504 | luaV_execute(L, ci); /* run the function */ | 525 | return ci; |
505 | break; | ||
506 | } | 526 | } |
507 | default: { /* not a function */ | 527 | default: { /* not a function */ |
508 | checkstackGCp(L, 1, func); /* space for metamethod */ | 528 | checkstackGCp(L, 1, func); /* space for metamethod */ |
@@ -514,16 +534,36 @@ void luaD_call (lua_State *L, StkId func, int nresults) { | |||
514 | 534 | ||
515 | 535 | ||
516 | /* | 536 | /* |
537 | ** Call a function (C or Lua). 'inc' can be 1 (increment number | ||
538 | ** of recursive invocations in the C stack) or nyci (the same plus | ||
539 | ** increment number of non-yieldable calls). | ||
540 | */ | ||
541 | static void docall (lua_State *L, StkId func, int nResults, int inc) { | ||
542 | CallInfo *ci; | ||
543 | L->nCcalls += inc; | ||
544 | if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) | ||
545 | luaE_checkcstack(L); | ||
546 | if ((ci = luaD_precall(L, func, nResults)) != NULL) { /* Lua function? */ | ||
547 | ci->callstatus = CIST_FRESH; /* mark that it is a "fresh" execute */ | ||
548 | luaV_execute(L, ci); /* call it */ | ||
549 | } | ||
550 | L->nCcalls -= inc; | ||
551 | } | ||
552 | |||
553 | |||
554 | /* | ||
555 | ** External interface for 'docall' | ||
556 | */ | ||
557 | void luaD_call (lua_State *L, StkId func, int nResults) { | ||
558 | return docall(L, func, nResults, 1); | ||
559 | } | ||
560 | |||
561 | |||
562 | /* | ||
517 | ** Similar to 'luaD_call', but does not allow yields during the call. | 563 | ** Similar to 'luaD_call', but does not allow yields during the call. |
518 | */ | 564 | */ |
519 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { | 565 | void luaD_callnoyield (lua_State *L, StkId func, int nResults) { |
520 | incXCcalls(L); | 566 | return docall(L, func, nResults, nyci); |
521 | if (getCcalls(L) <= CSTACKERR) { /* possible C stack overflow? */ | ||
522 | luaE_exitCcall(L); /* to compensate decrement in next call */ | ||
523 | luaE_enterCcall(L); /* check properly */ | ||
524 | } | ||
525 | luaD_call(L, func, nResults); | ||
526 | decXCcalls(L); | ||
527 | } | 567 | } |
528 | 568 | ||
529 | 569 | ||
@@ -601,12 +641,12 @@ static int recover (lua_State *L, int status) { | |||
601 | if (ci == NULL) return 0; /* no recovery point */ | 641 | if (ci == NULL) return 0; /* no recovery point */ |
602 | /* "finish" luaD_pcall */ | 642 | /* "finish" luaD_pcall */ |
603 | oldtop = restorestack(L, ci->u2.funcidx); | 643 | oldtop = restorestack(L, ci->u2.funcidx); |
604 | luaF_close(L, oldtop, status); /* may change the stack */ | ||
605 | oldtop = restorestack(L, ci->u2.funcidx); | ||
606 | luaD_seterrorobj(L, status, oldtop); | ||
607 | L->ci = ci; | 644 | L->ci = ci; |
608 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ | 645 | L->allowhook = getoah(ci->callstatus); /* restore original 'allowhook' */ |
609 | luaD_shrinkstack(L); | 646 | status = luaF_close(L, oldtop, status); /* may change the stack */ |
647 | oldtop = restorestack(L, ci->u2.funcidx); | ||
648 | luaD_seterrorobj(L, status, oldtop); | ||
649 | luaD_shrinkstack(L); /* restore stack size in case of overflow */ | ||
610 | L->errfunc = ci->u.c.old_errfunc; | 650 | L->errfunc = ci->u.c.old_errfunc; |
611 | return 1; /* continue running the coroutine */ | 651 | return 1; /* continue running the coroutine */ |
612 | } | 652 | } |
@@ -637,12 +677,12 @@ static void resume (lua_State *L, void *ud) { | |||
637 | int n = *(cast(int*, ud)); /* number of arguments */ | 677 | int n = *(cast(int*, ud)); /* number of arguments */ |
638 | StkId firstArg = L->top - n; /* first argument */ | 678 | StkId firstArg = L->top - n; /* first argument */ |
639 | CallInfo *ci = L->ci; | 679 | CallInfo *ci = L->ci; |
640 | if (L->status == LUA_OK) { /* starting a coroutine? */ | 680 | if (L->status == LUA_OK) /* starting a coroutine? */ |
641 | luaD_call(L, firstArg - 1, LUA_MULTRET); | 681 | docall(L, firstArg - 1, LUA_MULTRET, 1); /* just call its body */ |
642 | } | ||
643 | else { /* resuming from previous yield */ | 682 | else { /* resuming from previous yield */ |
644 | lua_assert(L->status == LUA_YIELD); | 683 | lua_assert(L->status == LUA_YIELD); |
645 | L->status = LUA_OK; /* mark that it is running (again) */ | 684 | L->status = LUA_OK; /* mark that it is running (again) */ |
685 | luaE_incCstack(L); /* control the C stack */ | ||
646 | if (isLua(ci)) /* yielded inside a hook? */ | 686 | if (isLua(ci)) /* yielded inside a hook? */ |
647 | luaV_execute(L, ci); /* just continue running Lua code */ | 687 | luaV_execute(L, ci); /* just continue running Lua code */ |
648 | else { /* 'common' yield */ | 688 | else { /* 'common' yield */ |
@@ -670,12 +710,7 @@ LUA_API int lua_resume (lua_State *L, lua_State *from, int nargs, | |||
670 | } | 710 | } |
671 | else if (L->status != LUA_YIELD) /* ended with errors? */ | 711 | else if (L->status != LUA_YIELD) /* ended with errors? */ |
672 | return resume_error(L, "cannot resume dead coroutine", nargs); | 712 | return resume_error(L, "cannot resume dead coroutine", nargs); |
673 | if (from == NULL) | 713 | L->nCcalls = (from) ? getCcalls(from) : 0; |
674 | L->nCcalls = CSTACKTHREAD; | ||
675 | else /* correct 'nCcalls' for this thread */ | ||
676 | L->nCcalls = getCcalls(from) - L->nci - CSTACKCF; | ||
677 | if (L->nCcalls <= CSTACKERR) | ||
678 | return resume_error(L, "C stack overflow", nargs); | ||
679 | luai_userstateresume(L, nargs); | 714 | luai_userstateresume(L, nargs); |
680 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); | 715 | api_checknelems(L, (L->status == LUA_OK) ? nargs + 1 : nargs); |
681 | status = luaD_rawrunprotected(L, resume, &nargs); | 716 | status = luaD_rawrunprotected(L, resume, &nargs); |
@@ -754,7 +789,7 @@ int luaD_pcall (lua_State *L, Pfunc func, void *u, | |||
754 | status = luaF_close(L, oldtop, status); | 789 | status = luaF_close(L, oldtop, status); |
755 | oldtop = restorestack(L, old_top); /* previous call may change stack */ | 790 | oldtop = restorestack(L, old_top); /* previous call may change stack */ |
756 | luaD_seterrorobj(L, status, oldtop); | 791 | luaD_seterrorobj(L, status, oldtop); |
757 | luaD_shrinkstack(L); | 792 | luaD_shrinkstack(L); /* restore stack size in case of overflow */ |
758 | } | 793 | } |
759 | L->errfunc = old_errfunc; | 794 | L->errfunc = old_errfunc; |
760 | return status; | 795 | return status; |
diff --git a/src/lua/ldo.h b/src/lua/ldo.h index 6c6cb28..4d30d07 100644 --- a/src/lua/ldo.h +++ b/src/lua/ldo.h | |||
@@ -59,6 +59,7 @@ LUAI_FUNC void luaD_hook (lua_State *L, int event, int line, | |||
59 | int fTransfer, int nTransfer); | 59 | int fTransfer, int nTransfer); |
60 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); | 60 | LUAI_FUNC void luaD_hookcall (lua_State *L, CallInfo *ci); |
61 | LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); | 61 | LUAI_FUNC void luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func, int n); |
62 | LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults); | ||
62 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); | 63 | LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults); |
63 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); | 64 | LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults); |
64 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); | 65 | LUAI_FUNC void luaD_tryfuncTM (lua_State *L, StkId func); |
diff --git a/src/lua/lfunc.c b/src/lua/lfunc.c index 88d4532..c4360f0 100644 --- a/src/lua/lfunc.c +++ b/src/lua/lfunc.c | |||
@@ -53,7 +53,7 @@ void luaF_initupvals (lua_State *L, LClosure *cl) { | |||
53 | uv->v = &uv->u.value; /* make it closed */ | 53 | uv->v = &uv->u.value; /* make it closed */ |
54 | setnilvalue(uv->v); | 54 | setnilvalue(uv->v); |
55 | cl->upvals[i] = uv; | 55 | cl->upvals[i] = uv; |
56 | luaC_objbarrier(L, cl, o); | 56 | luaC_objbarrier(L, cl, uv); |
57 | } | 57 | } |
58 | } | 58 | } |
59 | 59 | ||
diff --git a/src/lua/lgc.c b/src/lua/lgc.c index 4a7bcae..5dba56f 100644 --- a/src/lua/lgc.c +++ b/src/lua/lgc.c | |||
@@ -161,18 +161,17 @@ static void linkgclist_ (GCObject *o, GCObject **pnext, GCObject **list) { | |||
161 | 161 | ||
162 | 162 | ||
163 | /* | 163 | /* |
164 | ** Clear keys for empty entries in tables. If entry is empty | 164 | ** Clear keys for empty entries in tables. If entry is empty, mark its |
165 | ** and its key is not marked, mark its entry as dead. This allows the | 165 | ** entry as dead. This allows the collection of the key, but keeps its |
166 | ** collection of the key, but keeps its entry in the table (its removal | 166 | ** entry in the table: its removal could break a chain and could break |
167 | ** could break a chain). The main feature of a dead key is that it must | 167 | ** a table traversal. Other places never manipulate dead keys, because |
168 | ** be different from any other value, to do not disturb searches. | 168 | ** its associated empty value is enough to signal that the entry is |
169 | ** Other places never manipulate dead keys, because its associated empty | 169 | ** logically empty. |
170 | ** value is enough to signal that the entry is logically empty. | ||
171 | */ | 170 | */ |
172 | static void clearkey (Node *n) { | 171 | static void clearkey (Node *n) { |
173 | lua_assert(isempty(gval(n))); | 172 | lua_assert(isempty(gval(n))); |
174 | if (keyiswhite(n)) | 173 | if (keyiscollectable(n)) |
175 | setdeadkey(n); /* unused and unmarked key; remove it */ | 174 | setdeadkey(n); /* unused key; remove it */ |
176 | } | 175 | } |
177 | 176 | ||
178 | 177 | ||
@@ -301,7 +300,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
301 | if (upisopen(uv)) | 300 | if (upisopen(uv)) |
302 | set2gray(uv); /* open upvalues are kept gray */ | 301 | set2gray(uv); /* open upvalues are kept gray */ |
303 | else | 302 | else |
304 | set2black(o); /* closed upvalues are visited here */ | 303 | set2black(uv); /* closed upvalues are visited here */ |
305 | markvalue(g, uv->v); /* mark its content */ | 304 | markvalue(g, uv->v); /* mark its content */ |
306 | break; | 305 | break; |
307 | } | 306 | } |
@@ -309,7 +308,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
309 | Udata *u = gco2u(o); | 308 | Udata *u = gco2u(o); |
310 | if (u->nuvalue == 0) { /* no user values? */ | 309 | if (u->nuvalue == 0) { /* no user values? */ |
311 | markobjectN(g, u->metatable); /* mark its metatable */ | 310 | markobjectN(g, u->metatable); /* mark its metatable */ |
312 | set2black(o); /* nothing else to mark */ | 311 | set2black(u); /* nothing else to mark */ |
313 | break; | 312 | break; |
314 | } | 313 | } |
315 | /* else... */ | 314 | /* else... */ |
@@ -633,8 +632,7 @@ static int traversethread (global_State *g, lua_State *th) { | |||
633 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) | 632 | for (uv = th->openupval; uv != NULL; uv = uv->u.open.next) |
634 | markobject(g, uv); /* open upvalues cannot be collected */ | 633 | markobject(g, uv); /* open upvalues cannot be collected */ |
635 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 634 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
636 | StkId lim = th->stack + th->stacksize; /* real end of stack */ | 635 | for (; o < th->stack_last; o++) /* clear not-marked stack slice */ |
637 | for (; o < lim; o++) /* clear not-marked stack slice */ | ||
638 | setnilvalue(s2v(o)); | 636 | setnilvalue(s2v(o)); |
639 | /* 'remarkupvals' may have removed thread from 'twups' list */ | 637 | /* 'remarkupvals' may have removed thread from 'twups' list */ |
640 | if (!isintwups(th) && th->openupval != NULL) { | 638 | if (!isintwups(th) && th->openupval != NULL) { |
@@ -644,7 +642,7 @@ static int traversethread (global_State *g, lua_State *th) { | |||
644 | } | 642 | } |
645 | else if (!g->gcemergency) | 643 | else if (!g->gcemergency) |
646 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ | 644 | luaD_shrinkstack(th); /* do not change stack in emergency cycle */ |
647 | return 1 + th->stacksize; | 645 | return 1 + stacksize(th); |
648 | } | 646 | } |
649 | 647 | ||
650 | 648 | ||
@@ -771,12 +769,16 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
771 | case LUA_VUPVAL: | 769 | case LUA_VUPVAL: |
772 | freeupval(L, gco2upv(o)); | 770 | freeupval(L, gco2upv(o)); |
773 | break; | 771 | break; |
774 | case LUA_VLCL: | 772 | case LUA_VLCL: { |
775 | luaM_freemem(L, o, sizeLclosure(gco2lcl(o)->nupvalues)); | 773 | LClosure *cl = gco2lcl(o); |
774 | luaM_freemem(L, cl, sizeLclosure(cl->nupvalues)); | ||
776 | break; | 775 | break; |
777 | case LUA_VCCL: | 776 | } |
778 | luaM_freemem(L, o, sizeCclosure(gco2ccl(o)->nupvalues)); | 777 | case LUA_VCCL: { |
778 | CClosure *cl = gco2ccl(o); | ||
779 | luaM_freemem(L, cl, sizeCclosure(cl->nupvalues)); | ||
779 | break; | 780 | break; |
781 | } | ||
780 | case LUA_VTABLE: | 782 | case LUA_VTABLE: |
781 | luaH_free(L, gco2t(o)); | 783 | luaH_free(L, gco2t(o)); |
782 | break; | 784 | break; |
@@ -788,13 +790,17 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
788 | luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); | 790 | luaM_freemem(L, o, sizeudata(u->nuvalue, u->len)); |
789 | break; | 791 | break; |
790 | } | 792 | } |
791 | case LUA_VSHRSTR: | 793 | case LUA_VSHRSTR: { |
792 | luaS_remove(L, gco2ts(o)); /* remove it from hash table */ | 794 | TString *ts = gco2ts(o); |
793 | luaM_freemem(L, o, sizelstring(gco2ts(o)->shrlen)); | 795 | luaS_remove(L, ts); /* remove it from hash table */ |
796 | luaM_freemem(L, ts, sizelstring(ts->shrlen)); | ||
794 | break; | 797 | break; |
795 | case LUA_VLNGSTR: | 798 | } |
796 | luaM_freemem(L, o, sizelstring(gco2ts(o)->u.lnglen)); | 799 | case LUA_VLNGSTR: { |
800 | TString *ts = gco2ts(o); | ||
801 | luaM_freemem(L, ts, sizelstring(ts->u.lnglen)); | ||
797 | break; | 802 | break; |
803 | } | ||
798 | default: lua_assert(0); | 804 | default: lua_assert(0); |
799 | } | 805 | } |
800 | } | 806 | } |
diff --git a/src/lua/llex.c b/src/lua/llex.c index 90a7951..3d6b2b9 100644 --- a/src/lua/llex.c +++ b/src/lua/llex.c | |||
@@ -81,7 +81,6 @@ void luaX_init (lua_State *L) { | |||
81 | 81 | ||
82 | const char *luaX_token2str (LexState *ls, int token) { | 82 | const char *luaX_token2str (LexState *ls, int token) { |
83 | if (token < FIRST_RESERVED) { /* single-byte symbols? */ | 83 | if (token < FIRST_RESERVED) { /* single-byte symbols? */ |
84 | lua_assert(token == cast_uchar(token)); | ||
85 | if (lisprint(token)) | 84 | if (lisprint(token)) |
86 | return luaO_pushfstring(ls->L, "'%c'", token); | 85 | return luaO_pushfstring(ls->L, "'%c'", token); |
87 | else /* control character */ | 86 | else /* control character */ |
diff --git a/src/lua/llex.h b/src/lua/llex.h index d1a4cba..389d2f8 100644 --- a/src/lua/llex.h +++ b/src/lua/llex.h | |||
@@ -7,11 +7,17 @@ | |||
7 | #ifndef llex_h | 7 | #ifndef llex_h |
8 | #define llex_h | 8 | #define llex_h |
9 | 9 | ||
10 | #include <limits.h> | ||
11 | |||
10 | #include "lobject.h" | 12 | #include "lobject.h" |
11 | #include "lzio.h" | 13 | #include "lzio.h" |
12 | 14 | ||
13 | 15 | ||
14 | #define FIRST_RESERVED 257 | 16 | /* |
17 | ** Single-char tokens (terminal symbols) are represented by their own | ||
18 | ** numeric code. Other tokens start at the following value. | ||
19 | */ | ||
20 | #define FIRST_RESERVED (UCHAR_MAX + 1) | ||
15 | 21 | ||
16 | 22 | ||
17 | #if !defined(LUA_ENV) | 23 | #if !defined(LUA_ENV) |
diff --git a/src/lua/llimits.h b/src/lua/llimits.h index 48c97f9..a76c13e 100644 --- a/src/lua/llimits.h +++ b/src/lua/llimits.h | |||
@@ -235,6 +235,17 @@ typedef l_uint32 Instruction; | |||
235 | 235 | ||
236 | 236 | ||
237 | /* | 237 | /* |
238 | ** Maximum depth for nested C calls, syntactical nested non-terminals, | ||
239 | ** and other features implemented through recursion in C. (Value must | ||
240 | ** fit in a 16-bit unsigned integer. It must also be compatible with | ||
241 | ** the size of the C stack.) | ||
242 | */ | ||
243 | #if !defined(LUAI_MAXCCALLS) | ||
244 | #define LUAI_MAXCCALLS 200 | ||
245 | #endif | ||
246 | |||
247 | |||
248 | /* | ||
238 | ** macros that are executed whenever program enters the Lua core | 249 | ** macros that are executed whenever program enters the Lua core |
239 | ** ('lua_lock') and leaves the core ('lua_unlock') | 250 | ** ('lua_lock') and leaves the core ('lua_unlock') |
240 | */ | 251 | */ |
@@ -344,7 +355,7 @@ typedef l_uint32 Instruction; | |||
344 | #else | 355 | #else |
345 | /* realloc stack keeping its size */ | 356 | /* realloc stack keeping its size */ |
346 | #define condmovestack(L,pre,pos) \ | 357 | #define condmovestack(L,pre,pos) \ |
347 | { int sz_ = (L)->stacksize; pre; luaD_reallocstack((L), sz_, 0); pos; } | 358 | { int sz_ = stacksize(L); pre; luaD_reallocstack((L), sz_, 0); pos; } |
348 | #endif | 359 | #endif |
349 | 360 | ||
350 | #if !defined(HARDMEMTESTS) | 361 | #if !defined(HARDMEMTESTS) |
diff --git a/src/lua/lobject.h b/src/lua/lobject.h index a9d4578..1cc8e75 100644 --- a/src/lua/lobject.h +++ b/src/lua/lobject.h | |||
@@ -21,10 +21,12 @@ | |||
21 | */ | 21 | */ |
22 | #define LUA_TUPVAL LUA_NUMTYPES /* upvalues */ | 22 | #define LUA_TUPVAL LUA_NUMTYPES /* upvalues */ |
23 | #define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */ | 23 | #define LUA_TPROTO (LUA_NUMTYPES+1) /* function prototypes */ |
24 | #define LUA_TDEADKEY (LUA_NUMTYPES+2) /* removed keys in tables */ | ||
25 | |||
24 | 26 | ||
25 | 27 | ||
26 | /* | 28 | /* |
27 | ** number of all possible types (including LUA_TNONE) | 29 | ** number of all possible types (including LUA_TNONE but excluding DEADKEY) |
28 | */ | 30 | */ |
29 | #define LUA_TOTALTYPES (LUA_TPROTO + 2) | 31 | #define LUA_TOTALTYPES (LUA_TPROTO + 2) |
30 | 32 | ||
@@ -555,7 +557,7 @@ typedef struct Proto { | |||
555 | 557 | ||
556 | /* | 558 | /* |
557 | ** {================================================================== | 559 | ** {================================================================== |
558 | ** Closures | 560 | ** Functions |
559 | ** =================================================================== | 561 | ** =================================================================== |
560 | */ | 562 | */ |
561 | 563 | ||
@@ -743,13 +745,13 @@ typedef struct Table { | |||
743 | 745 | ||
744 | 746 | ||
745 | /* | 747 | /* |
746 | ** Use a "nil table" to mark dead keys in a table. Those keys serve | 748 | ** Dead keys in tables have the tag DEADKEY but keep their original |
747 | ** to keep space for removed entries, which may still be part of | 749 | ** gcvalue. This distinguishes them from regular keys but allows them to |
748 | ** chains. Note that the 'keytt' does not have the BIT_ISCOLLECTABLE | 750 | ** be found when searched in a special way. ('next' needs that to find |
749 | ** set, so these values are considered not collectable and are different | 751 | ** keys removed from a table during a traversal.) |
750 | ** from any valid value. | ||
751 | */ | 752 | */ |
752 | #define setdeadkey(n) (keytt(n) = LUA_TTABLE, gckey(n) = NULL) | 753 | #define setdeadkey(node) (keytt(node) = LUA_TDEADKEY) |
754 | #define keyisdead(node) (keytt(node) == LUA_TDEADKEY) | ||
753 | 755 | ||
754 | /* }================================================================== */ | 756 | /* }================================================================== */ |
755 | 757 | ||
diff --git a/src/lua/lopcodes.h b/src/lua/lopcodes.h index 122e5d2..120cdd9 100644 --- a/src/lua/lopcodes.h +++ b/src/lua/lopcodes.h | |||
@@ -261,7 +261,7 @@ OP_MMBINK,/* A B C k call C metamethod over R[A] and K[B] */ | |||
261 | OP_UNM,/* A B R[A] := -R[B] */ | 261 | OP_UNM,/* A B R[A] := -R[B] */ |
262 | OP_BNOT,/* A B R[A] := ~R[B] */ | 262 | OP_BNOT,/* A B R[A] := ~R[B] */ |
263 | OP_NOT,/* A B R[A] := not R[B] */ | 263 | OP_NOT,/* A B R[A] := not R[B] */ |
264 | OP_LEN,/* A B R[A] := length of R[B] */ | 264 | OP_LEN,/* A B R[A] := #R[B] (length operator) */ |
265 | 265 | ||
266 | OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */ | 266 | OP_CONCAT,/* A B R[A] := R[A].. ... ..R[A + B - 1] */ |
267 | 267 | ||
@@ -297,7 +297,7 @@ OP_TFORPREP,/* A Bx create upvalue for R[A + 3]; pc+=Bx */ | |||
297 | OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ | 297 | OP_TFORCALL,/* A C R[A+4], ... ,R[A+3+C] := R[A](R[A+1], R[A+2]); */ |
298 | OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ | 298 | OP_TFORLOOP,/* A Bx if R[A+2] ~= nil then { R[A]=R[A+2]; pc -= Bx } */ |
299 | 299 | ||
300 | OP_SETLIST,/* A B C k R[A][(C-1)*FPF+i] := R[A+i], 1 <= i <= B */ | 300 | OP_SETLIST,/* A B C k R[A][C+i] := R[A+i], 1 <= i <= B */ |
301 | 301 | ||
302 | OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ | 302 | OP_CLOSURE,/* A Bx R[A] := closure(KPROTO[Bx]) */ |
303 | 303 | ||
diff --git a/src/lua/lparser.c b/src/lua/lparser.c index bc7d9a4..bcdcfb6 100644 --- a/src/lua/lparser.c +++ b/src/lua/lparser.c | |||
@@ -489,12 +489,10 @@ static void adjust_assign (LexState *ls, int nvars, int nexps, expdesc *e) { | |||
489 | } | 489 | } |
490 | 490 | ||
491 | 491 | ||
492 | /* | 492 | #define enterlevel(ls) luaE_incCstack(ls->L) |
493 | ** Macros to limit the maximum recursion depth while parsing | 493 | |
494 | */ | ||
495 | #define enterlevel(ls) luaE_enterCcall((ls)->L) | ||
496 | 494 | ||
497 | #define leavelevel(ls) luaE_exitCcall((ls)->L) | 495 | #define leavelevel(ls) ((ls)->L->nCcalls--) |
498 | 496 | ||
499 | 497 | ||
500 | /* | 498 | /* |
diff --git a/src/lua/lstate.c b/src/lua/lstate.c index 86b3761..4227429 100644 --- a/src/lua/lstate.c +++ b/src/lua/lstate.c | |||
@@ -76,7 +76,7 @@ static unsigned int luai_makeseed (lua_State *L) { | |||
76 | addbuff(buff, p, &h); /* local variable */ | 76 | addbuff(buff, p, &h); /* local variable */ |
77 | addbuff(buff, p, &lua_newstate); /* public function */ | 77 | addbuff(buff, p, &lua_newstate); /* public function */ |
78 | lua_assert(p == sizeof(buff)); | 78 | lua_assert(p == sizeof(buff)); |
79 | return luaS_hash(buff, p, h, 1); | 79 | return luaS_hash(buff, p, h); |
80 | } | 80 | } |
81 | 81 | ||
82 | #endif | 82 | #endif |
@@ -97,66 +97,14 @@ void luaE_setdebt (global_State *g, l_mem debt) { | |||
97 | 97 | ||
98 | 98 | ||
99 | LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { | 99 | LUA_API int lua_setcstacklimit (lua_State *L, unsigned int limit) { |
100 | global_State *g = G(L); | 100 | UNUSED(L); UNUSED(limit); |
101 | int ccalls; | 101 | return LUAI_MAXCCALLS; /* warning?? */ |
102 | luaE_freeCI(L); /* release unused CIs */ | ||
103 | ccalls = getCcalls(L); | ||
104 | if (limit >= 40000) | ||
105 | return 0; /* out of bounds */ | ||
106 | limit += CSTACKERR; | ||
107 | if (L != g-> mainthread) | ||
108 | return 0; /* only main thread can change the C stack */ | ||
109 | else if (ccalls <= CSTACKERR) | ||
110 | return 0; /* handling overflow */ | ||
111 | else { | ||
112 | int diff = limit - g->Cstacklimit; | ||
113 | if (ccalls + diff <= CSTACKERR) | ||
114 | return 0; /* new limit would cause an overflow */ | ||
115 | g->Cstacklimit = limit; /* set new limit */ | ||
116 | L->nCcalls += diff; /* correct 'nCcalls' */ | ||
117 | return limit - diff - CSTACKERR; /* success; return previous limit */ | ||
118 | } | ||
119 | } | ||
120 | |||
121 | |||
122 | /* | ||
123 | ** Decrement count of "C calls" and check for overflows. In case of | ||
124 | ** a stack overflow, check appropriate error ("regular" overflow or | ||
125 | ** overflow while handling stack overflow). If 'nCcalls' is smaller | ||
126 | ** than CSTACKERR but larger than CSTACKMARK, it means it has just | ||
127 | ** entered the "overflow zone", so the function raises an overflow | ||
128 | ** error. If 'nCcalls' is smaller than CSTACKMARK (which means it is | ||
129 | ** already handling an overflow) but larger than CSTACKERRMARK, does | ||
130 | ** not report an error (to allow message handling to work). Otherwise, | ||
131 | ** report a stack overflow while handling a stack overflow (probably | ||
132 | ** caused by a repeating error in the message handling function). | ||
133 | */ | ||
134 | |||
135 | void luaE_enterCcall (lua_State *L) { | ||
136 | int ncalls = getCcalls(L); | ||
137 | L->nCcalls--; | ||
138 | if (ncalls <= CSTACKERR) { /* possible overflow? */ | ||
139 | luaE_freeCI(L); /* release unused CIs */ | ||
140 | ncalls = getCcalls(L); /* update call count */ | ||
141 | if (ncalls <= CSTACKERR) { /* still overflow? */ | ||
142 | if (ncalls <= CSTACKERRMARK) /* below error-handling zone? */ | ||
143 | luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ | ||
144 | else if (ncalls >= CSTACKMARK) { | ||
145 | /* not in error-handling zone; raise the error now */ | ||
146 | L->nCcalls = (CSTACKMARK - 1); /* enter error-handling zone */ | ||
147 | luaG_runerror(L, "C stack overflow"); | ||
148 | } | ||
149 | /* else stack is in the error-handling zone; | ||
150 | allow message handler to work */ | ||
151 | } | ||
152 | } | ||
153 | } | 102 | } |
154 | 103 | ||
155 | 104 | ||
156 | CallInfo *luaE_extendCI (lua_State *L) { | 105 | CallInfo *luaE_extendCI (lua_State *L) { |
157 | CallInfo *ci; | 106 | CallInfo *ci; |
158 | lua_assert(L->ci->next == NULL); | 107 | lua_assert(L->ci->next == NULL); |
159 | luaE_enterCcall(L); | ||
160 | ci = luaM_new(L, CallInfo); | 108 | ci = luaM_new(L, CallInfo); |
161 | lua_assert(L->ci->next == NULL); | 109 | lua_assert(L->ci->next == NULL); |
162 | L->ci->next = ci; | 110 | L->ci->next = ci; |
@@ -175,13 +123,11 @@ void luaE_freeCI (lua_State *L) { | |||
175 | CallInfo *ci = L->ci; | 123 | CallInfo *ci = L->ci; |
176 | CallInfo *next = ci->next; | 124 | CallInfo *next = ci->next; |
177 | ci->next = NULL; | 125 | ci->next = NULL; |
178 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ | ||
179 | while ((ci = next) != NULL) { | 126 | while ((ci = next) != NULL) { |
180 | next = ci->next; | 127 | next = ci->next; |
181 | luaM_free(L, ci); | 128 | luaM_free(L, ci); |
182 | L->nci--; | 129 | L->nci--; |
183 | } | 130 | } |
184 | L->nCcalls -= L->nci; /* adjust result */ | ||
185 | } | 131 | } |
186 | 132 | ||
187 | 133 | ||
@@ -194,7 +140,6 @@ void luaE_shrinkCI (lua_State *L) { | |||
194 | CallInfo *next; | 140 | CallInfo *next; |
195 | if (ci == NULL) | 141 | if (ci == NULL) |
196 | return; /* no extra elements */ | 142 | return; /* no extra elements */ |
197 | L->nCcalls += L->nci; /* add removed elements back to 'nCcalls' */ | ||
198 | while ((next = ci->next) != NULL) { /* two extra elements? */ | 143 | while ((next = ci->next) != NULL) { /* two extra elements? */ |
199 | CallInfo *next2 = next->next; /* next's next */ | 144 | CallInfo *next2 = next->next; /* next's next */ |
200 | ci->next = next2; /* remove next from the list */ | 145 | ci->next = next2; /* remove next from the list */ |
@@ -207,19 +152,39 @@ void luaE_shrinkCI (lua_State *L) { | |||
207 | ci = next2; /* continue */ | 152 | ci = next2; /* continue */ |
208 | } | 153 | } |
209 | } | 154 | } |
210 | L->nCcalls -= L->nci; /* adjust result */ | 155 | } |
156 | |||
157 | |||
158 | /* | ||
159 | ** Called when 'getCcalls(L)' larger or equal to LUAI_MAXCCALLS. | ||
160 | ** If equal, raises an overflow error. If value is larger than | ||
161 | ** LUAI_MAXCCALLS (which means it is handling an overflow) but | ||
162 | ** not much larger, does not report an error (to allow overflow | ||
163 | ** handling to work). | ||
164 | */ | ||
165 | void luaE_checkcstack (lua_State *L) { | ||
166 | if (getCcalls(L) == LUAI_MAXCCALLS) | ||
167 | luaG_runerror(L, "C stack overflow"); | ||
168 | else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) | ||
169 | luaD_throw(L, LUA_ERRERR); /* error while handing stack error */ | ||
170 | } | ||
171 | |||
172 | |||
173 | LUAI_FUNC void luaE_incCstack (lua_State *L) { | ||
174 | L->nCcalls++; | ||
175 | if (unlikely(getCcalls(L) >= LUAI_MAXCCALLS)) | ||
176 | luaE_checkcstack(L); | ||
211 | } | 177 | } |
212 | 178 | ||
213 | 179 | ||
214 | static void stack_init (lua_State *L1, lua_State *L) { | 180 | static void stack_init (lua_State *L1, lua_State *L) { |
215 | int i; CallInfo *ci; | 181 | int i; CallInfo *ci; |
216 | /* initialize stack array */ | 182 | /* initialize stack array */ |
217 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE, StackValue); | 183 | L1->stack = luaM_newvector(L, BASIC_STACK_SIZE + EXTRA_STACK, StackValue); |
218 | L1->stacksize = BASIC_STACK_SIZE; | ||
219 | for (i = 0; i < BASIC_STACK_SIZE; i++) | 184 | for (i = 0; i < BASIC_STACK_SIZE; i++) |
220 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ | 185 | setnilvalue(s2v(L1->stack + i)); /* erase new stack */ |
221 | L1->top = L1->stack; | 186 | L1->top = L1->stack; |
222 | L1->stack_last = L1->stack + L1->stacksize - EXTRA_STACK; | 187 | L1->stack_last = L1->stack + BASIC_STACK_SIZE; |
223 | /* initialize first ci */ | 188 | /* initialize first ci */ |
224 | ci = &L1->base_ci; | 189 | ci = &L1->base_ci; |
225 | ci->next = ci->previous = NULL; | 190 | ci->next = ci->previous = NULL; |
@@ -240,7 +205,7 @@ static void freestack (lua_State *L) { | |||
240 | L->ci = &L->base_ci; /* free the entire 'ci' list */ | 205 | L->ci = &L->base_ci; /* free the entire 'ci' list */ |
241 | luaE_freeCI(L); | 206 | luaE_freeCI(L); |
242 | lua_assert(L->nci == 0); | 207 | lua_assert(L->nci == 0); |
243 | luaM_freearray(L, L->stack, L->stacksize); /* free stack array */ | 208 | luaM_freearray(L, L->stack, stacksize(L) + EXTRA_STACK); /* free stack */ |
244 | } | 209 | } |
245 | 210 | ||
246 | 211 | ||
@@ -290,7 +255,6 @@ static void preinit_thread (lua_State *L, global_State *g) { | |||
290 | L->stack = NULL; | 255 | L->stack = NULL; |
291 | L->ci = NULL; | 256 | L->ci = NULL; |
292 | L->nci = 0; | 257 | L->nci = 0; |
293 | L->stacksize = 0; | ||
294 | L->twups = L; /* thread has no upvalues */ | 258 | L->twups = L; /* thread has no upvalues */ |
295 | L->errorJmp = NULL; | 259 | L->errorJmp = NULL; |
296 | L->hook = NULL; | 260 | L->hook = NULL; |
@@ -335,7 +299,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) { | |||
335 | setthvalue2s(L, L->top, L1); | 299 | setthvalue2s(L, L->top, L1); |
336 | api_incr_top(L); | 300 | api_incr_top(L); |
337 | preinit_thread(L1, g); | 301 | preinit_thread(L1, g); |
338 | L1->nCcalls = getCcalls(L); | 302 | L1->nCcalls = 0; |
339 | L1->hookmask = L->hookmask; | 303 | L1->hookmask = L->hookmask; |
340 | L1->basehookcount = L->basehookcount; | 304 | L1->basehookcount = L->basehookcount; |
341 | L1->hook = L->hook; | 305 | L1->hook = L->hook; |
@@ -396,7 +360,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
396 | preinit_thread(L, g); | 360 | preinit_thread(L, g); |
397 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ | 361 | g->allgc = obj2gco(L); /* by now, only object is the main thread */ |
398 | L->next = NULL; | 362 | L->next = NULL; |
399 | g->Cstacklimit = L->nCcalls = LUAI_MAXCSTACK + CSTACKERR; | 363 | L->nCcalls = 0; |
400 | incnny(L); /* main thread is always non yieldable */ | 364 | incnny(L); /* main thread is always non yieldable */ |
401 | g->frealloc = f; | 365 | g->frealloc = f; |
402 | g->ud = ud; | 366 | g->ud = ud; |
diff --git a/src/lua/lstate.h b/src/lua/lstate.h index 1b6bcdf..cbcf07e 100644 --- a/src/lua/lstate.h +++ b/src/lua/lstate.h | |||
@@ -87,48 +87,12 @@ | |||
87 | 87 | ||
88 | 88 | ||
89 | /* | 89 | /* |
90 | ** About 'nCcalls': each thread in Lua (a lua_State) keeps a count of | 90 | ** About 'nCcalls': This count has two parts: the lower 16 bits counts |
91 | ** how many "C calls" it still can do in the C stack, to avoid C-stack | 91 | ** the number of recursive invocations in the C stack; the higher |
92 | ** overflow. This count is very rough approximation; it considers only | 92 | ** 16 bits counts the number of non-yieldable calls in the stack. |
93 | ** recursive functions inside the interpreter, as non-recursive calls | 93 | ** (They are together so that we can change and save both with one |
94 | ** can be considered using a fixed (although unknown) amount of stack | 94 | ** instruction.) |
95 | ** space. | ||
96 | ** | ||
97 | ** The count has two parts: the lower part is the count itself; the | ||
98 | ** higher part counts the number of non-yieldable calls in the stack. | ||
99 | ** (They are together so that we can change both with one instruction.) | ||
100 | ** | ||
101 | ** Because calls to external C functions can use an unknown amount | ||
102 | ** of space (e.g., functions using an auxiliary buffer), calls | ||
103 | ** to these functions add more than one to the count (see CSTACKCF). | ||
104 | ** | ||
105 | ** The proper count excludes the number of CallInfo structures allocated | ||
106 | ** by Lua, as a kind of "potential" calls. So, when Lua calls a function | ||
107 | ** (and "consumes" one CallInfo), it needs neither to decrement nor to | ||
108 | ** check 'nCcalls', as its use of C stack is already accounted for. | ||
109 | */ | ||
110 | |||
111 | /* number of "C stack slots" used by an external C function */ | ||
112 | #define CSTACKCF 10 | ||
113 | |||
114 | |||
115 | /* | ||
116 | ** The C-stack size is sliced in the following zones: | ||
117 | ** - larger than CSTACKERR: normal stack; | ||
118 | ** - [CSTACKMARK, CSTACKERR]: buffer zone to signal a stack overflow; | ||
119 | ** - [CSTACKCF, CSTACKERRMARK]: error-handling zone; | ||
120 | ** - below CSTACKERRMARK: buffer zone to signal overflow during overflow; | ||
121 | ** (Because the counter can be decremented CSTACKCF at once, we need | ||
122 | ** the so called "buffer zones", with at least that size, to properly | ||
123 | ** detect a change from one zone to the next.) | ||
124 | */ | 95 | */ |
125 | #define CSTACKERR (8 * CSTACKCF) | ||
126 | #define CSTACKMARK (CSTACKERR - (CSTACKCF + 2)) | ||
127 | #define CSTACKERRMARK (CSTACKCF + 2) | ||
128 | |||
129 | |||
130 | /* initial limit for the C-stack of threads */ | ||
131 | #define CSTACKTHREAD (2 * CSTACKERR) | ||
132 | 96 | ||
133 | 97 | ||
134 | /* true if this thread does not have non-yieldable calls in the stack */ | 98 | /* true if this thread does not have non-yieldable calls in the stack */ |
@@ -144,13 +108,8 @@ | |||
144 | /* Decrement the number of non-yieldable calls */ | 108 | /* Decrement the number of non-yieldable calls */ |
145 | #define decnny(L) ((L)->nCcalls -= 0x10000) | 109 | #define decnny(L) ((L)->nCcalls -= 0x10000) |
146 | 110 | ||
147 | /* Increment the number of non-yieldable calls and decrement nCcalls */ | 111 | /* Non-yieldable call increment */ |
148 | #define incXCcalls(L) ((L)->nCcalls += 0x10000 - CSTACKCF) | 112 | #define nyci (0x10000 | 1) |
149 | |||
150 | /* Decrement the number of non-yieldable calls and increment nCcalls */ | ||
151 | #define decXCcalls(L) ((L)->nCcalls -= 0x10000 - CSTACKCF) | ||
152 | |||
153 | |||
154 | 113 | ||
155 | 114 | ||
156 | 115 | ||
@@ -168,12 +127,20 @@ struct lua_longjmp; /* defined in ldo.c */ | |||
168 | #endif | 127 | #endif |
169 | 128 | ||
170 | 129 | ||
171 | /* extra stack space to handle TM calls and some other extras */ | 130 | /* |
131 | ** Extra stack space to handle TM calls and some other extras. This | ||
132 | ** space is not included in 'stack_last'. It is used only to avoid stack | ||
133 | ** checks, either because the element will be promptly popped or because | ||
134 | ** there will be a stack check soon after the push. Function frames | ||
135 | ** never use this extra space, so it does not need to be kept clean. | ||
136 | */ | ||
172 | #define EXTRA_STACK 5 | 137 | #define EXTRA_STACK 5 |
173 | 138 | ||
174 | 139 | ||
175 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) | 140 | #define BASIC_STACK_SIZE (2*LUA_MINSTACK) |
176 | 141 | ||
142 | #define stacksize(th) cast_int((th)->stack_last - (th)->stack) | ||
143 | |||
177 | 144 | ||
178 | /* kinds of Garbage Collection */ | 145 | /* kinds of Garbage Collection */ |
179 | #define KGC_INC 0 /* incremental gc */ | 146 | #define KGC_INC 0 /* incremental gc */ |
@@ -224,14 +191,15 @@ typedef struct CallInfo { | |||
224 | */ | 191 | */ |
225 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ | 192 | #define CIST_OAH (1<<0) /* original value of 'allowhook' */ |
226 | #define CIST_C (1<<1) /* call is running a C function */ | 193 | #define CIST_C (1<<1) /* call is running a C function */ |
227 | #define CIST_HOOKED (1<<2) /* call is running a debug hook */ | 194 | #define CIST_FRESH (1<<2) /* call is on a fresh "luaV_execute" frame */ |
228 | #define CIST_YPCALL (1<<3) /* call is a yieldable protected call */ | 195 | #define CIST_HOOKED (1<<3) /* call is running a debug hook */ |
229 | #define CIST_TAIL (1<<4) /* call was tail called */ | 196 | #define CIST_YPCALL (1<<4) /* call is a yieldable protected call */ |
230 | #define CIST_HOOKYIELD (1<<5) /* last hook called yielded */ | 197 | #define CIST_TAIL (1<<5) /* call was tail called */ |
231 | #define CIST_FIN (1<<6) /* call is running a finalizer */ | 198 | #define CIST_HOOKYIELD (1<<6) /* last hook called yielded */ |
232 | #define CIST_TRAN (1<<7) /* 'ci' has transfer information */ | 199 | #define CIST_FIN (1<<7) /* call is running a finalizer */ |
200 | #define CIST_TRAN (1<<8) /* 'ci' has transfer information */ | ||
233 | #if defined(LUA_COMPAT_LT_LE) | 201 | #if defined(LUA_COMPAT_LT_LE) |
234 | #define CIST_LEQ (1<<8) /* using __lt for __le */ | 202 | #define CIST_LEQ (1<<9) /* using __lt for __le */ |
235 | #endif | 203 | #endif |
236 | 204 | ||
237 | /* active function is a Lua function */ | 205 | /* active function is a Lua function */ |
@@ -296,7 +264,6 @@ typedef struct global_State { | |||
296 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ | 264 | TString *strcache[STRCACHE_N][STRCACHE_M]; /* cache for strings in API */ |
297 | lua_WarnFunction warnf; /* warning function */ | 265 | lua_WarnFunction warnf; /* warning function */ |
298 | void *ud_warn; /* auxiliary data to 'warnf' */ | 266 | void *ud_warn; /* auxiliary data to 'warnf' */ |
299 | unsigned int Cstacklimit; /* current limit for the C stack */ | ||
300 | } global_State; | 267 | } global_State; |
301 | 268 | ||
302 | 269 | ||
@@ -311,7 +278,7 @@ struct lua_State { | |||
311 | StkId top; /* first free slot in the stack */ | 278 | StkId top; /* first free slot in the stack */ |
312 | global_State *l_G; | 279 | global_State *l_G; |
313 | CallInfo *ci; /* call info for current function */ | 280 | CallInfo *ci; /* call info for current function */ |
314 | StkId stack_last; /* last free slot in the stack */ | 281 | StkId stack_last; /* end of stack (last element + 1) */ |
315 | StkId stack; /* stack base */ | 282 | StkId stack; /* stack base */ |
316 | UpVal *openupval; /* list of open upvalues in this stack */ | 283 | UpVal *openupval; /* list of open upvalues in this stack */ |
317 | GCObject *gclist; | 284 | GCObject *gclist; |
@@ -320,9 +287,8 @@ struct lua_State { | |||
320 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ | 287 | CallInfo base_ci; /* CallInfo for first level (C calling Lua) */ |
321 | volatile lua_Hook hook; | 288 | volatile lua_Hook hook; |
322 | ptrdiff_t errfunc; /* current error handling function (stack index) */ | 289 | ptrdiff_t errfunc; /* current error handling function (stack index) */ |
323 | l_uint32 nCcalls; /* number of allowed nested C calls - 'nci' */ | 290 | l_uint32 nCcalls; /* number of nested (non-yieldable | C) calls */ |
324 | int oldpc; /* last pc traced */ | 291 | int oldpc; /* last pc traced */ |
325 | int stacksize; | ||
326 | int basehookcount; | 292 | int basehookcount; |
327 | int hookcount; | 293 | int hookcount; |
328 | volatile l_signalT hookmask; | 294 | volatile l_signalT hookmask; |
@@ -334,6 +300,12 @@ struct lua_State { | |||
334 | 300 | ||
335 | /* | 301 | /* |
336 | ** Union of all collectable objects (only for conversions) | 302 | ** Union of all collectable objects (only for conversions) |
303 | ** ISO C99, 6.5.2.3 p.5: | ||
304 | ** "if a union contains several structures that share a common initial | ||
305 | ** sequence [...], and if the union object currently contains one | ||
306 | ** of these structures, it is permitted to inspect the common initial | ||
307 | ** part of any of them anywhere that a declaration of the complete type | ||
308 | ** of the union is visible." | ||
337 | */ | 309 | */ |
338 | union GCUnion { | 310 | union GCUnion { |
339 | GCObject gc; /* common header */ | 311 | GCObject gc; /* common header */ |
@@ -347,6 +319,11 @@ union GCUnion { | |||
347 | }; | 319 | }; |
348 | 320 | ||
349 | 321 | ||
322 | /* | ||
323 | ** ISO C99, 6.7.2.1 p.14: | ||
324 | ** "A pointer to a union object, suitably converted, points to each of | ||
325 | ** its members [...], and vice versa." | ||
326 | */ | ||
350 | #define cast_u(o) cast(union GCUnion *, (o)) | 327 | #define cast_u(o) cast(union GCUnion *, (o)) |
351 | 328 | ||
352 | /* macros to convert a GCObject into a specific value */ | 329 | /* macros to convert a GCObject into a specific value */ |
@@ -378,12 +355,11 @@ LUAI_FUNC void luaE_freethread (lua_State *L, lua_State *L1); | |||
378 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); | 355 | LUAI_FUNC CallInfo *luaE_extendCI (lua_State *L); |
379 | LUAI_FUNC void luaE_freeCI (lua_State *L); | 356 | LUAI_FUNC void luaE_freeCI (lua_State *L); |
380 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); | 357 | LUAI_FUNC void luaE_shrinkCI (lua_State *L); |
381 | LUAI_FUNC void luaE_enterCcall (lua_State *L); | 358 | LUAI_FUNC void luaE_checkcstack (lua_State *L); |
359 | LUAI_FUNC void luaE_incCstack (lua_State *L); | ||
382 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); | 360 | LUAI_FUNC void luaE_warning (lua_State *L, const char *msg, int tocont); |
383 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); | 361 | LUAI_FUNC void luaE_warnerror (lua_State *L, const char *where); |
384 | 362 | ||
385 | 363 | ||
386 | #define luaE_exitCcall(L) ((L)->nCcalls++) | ||
387 | |||
388 | #endif | 364 | #endif |
389 | 365 | ||
diff --git a/src/lua/lstring.c b/src/lua/lstring.c index 6f15747..138871c 100644 --- a/src/lua/lstring.c +++ b/src/lua/lstring.c | |||
@@ -23,16 +23,6 @@ | |||
23 | 23 | ||
24 | 24 | ||
25 | /* | 25 | /* |
26 | ** Lua will use at most ~(2^LUAI_HASHLIMIT) bytes from a long string to | ||
27 | ** compute its hash | ||
28 | */ | ||
29 | #if !defined(LUAI_HASHLIMIT) | ||
30 | #define LUAI_HASHLIMIT 5 | ||
31 | #endif | ||
32 | |||
33 | |||
34 | |||
35 | /* | ||
36 | ** Maximum size for string table. | 26 | ** Maximum size for string table. |
37 | */ | 27 | */ |
38 | #define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) | 28 | #define MAXSTRTB cast_int(luaM_limitN(MAX_INT, TString*)) |
@@ -50,10 +40,9 @@ int luaS_eqlngstr (TString *a, TString *b) { | |||
50 | } | 40 | } |
51 | 41 | ||
52 | 42 | ||
53 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed, | 43 | unsigned int luaS_hash (const char *str, size_t l, unsigned int seed) { |
54 | size_t step) { | ||
55 | unsigned int h = seed ^ cast_uint(l); | 44 | unsigned int h = seed ^ cast_uint(l); |
56 | for (; l >= step; l -= step) | 45 | for (; l > 0; l--) |
57 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); | 46 | h ^= ((h<<5) + (h>>2) + cast_byte(str[l - 1])); |
58 | return h; | 47 | return h; |
59 | } | 48 | } |
@@ -63,8 +52,7 @@ unsigned int luaS_hashlongstr (TString *ts) { | |||
63 | lua_assert(ts->tt == LUA_VLNGSTR); | 52 | lua_assert(ts->tt == LUA_VLNGSTR); |
64 | if (ts->extra == 0) { /* no hash? */ | 53 | if (ts->extra == 0) { /* no hash? */ |
65 | size_t len = ts->u.lnglen; | 54 | size_t len = ts->u.lnglen; |
66 | size_t step = (len >> LUAI_HASHLIMIT) + 1; | 55 | ts->hash = luaS_hash(getstr(ts), len, ts->hash); |
67 | ts->hash = luaS_hash(getstr(ts), len, ts->hash, step); | ||
68 | ts->extra = 1; /* now it has its hash */ | 56 | ts->extra = 1; /* now it has its hash */ |
69 | } | 57 | } |
70 | return ts->hash; | 58 | return ts->hash; |
@@ -201,7 +189,7 @@ static TString *internshrstr (lua_State *L, const char *str, size_t l) { | |||
201 | TString *ts; | 189 | TString *ts; |
202 | global_State *g = G(L); | 190 | global_State *g = G(L); |
203 | stringtable *tb = &g->strt; | 191 | stringtable *tb = &g->strt; |
204 | unsigned int h = luaS_hash(str, l, g->seed, 1); | 192 | unsigned int h = luaS_hash(str, l, g->seed); |
205 | TString **list = &tb->hash[lmod(h, tb->size)]; | 193 | TString **list = &tb->hash[lmod(h, tb->size)]; |
206 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ | 194 | lua_assert(str != NULL); /* otherwise 'memcmp'/'memcpy' are undefined */ |
207 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { | 195 | for (ts = *list; ts != NULL; ts = ts->u.hnext) { |
diff --git a/src/lua/lstring.h b/src/lua/lstring.h index a413a9d..450c239 100644 --- a/src/lua/lstring.h +++ b/src/lua/lstring.h | |||
@@ -41,8 +41,7 @@ | |||
41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) | 41 | #define eqshrstr(a,b) check_exp((a)->tt == LUA_VSHRSTR, (a) == (b)) |
42 | 42 | ||
43 | 43 | ||
44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, | 44 | LUAI_FUNC unsigned int luaS_hash (const char *str, size_t l, unsigned int seed); |
45 | unsigned int seed, size_t step); | ||
46 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); | 45 | LUAI_FUNC unsigned int luaS_hashlongstr (TString *ts); |
47 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); | 46 | LUAI_FUNC int luaS_eqlngstr (TString *a, TString *b); |
48 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); | 47 | LUAI_FUNC void luaS_resize (lua_State *L, int newsize); |
diff --git a/src/lua/lstrlib.c b/src/lua/lstrlib.c index 2ba8bde..940a14c 100644 --- a/src/lua/lstrlib.c +++ b/src/lua/lstrlib.c | |||
@@ -1365,7 +1365,6 @@ typedef union Ftypes { | |||
1365 | float f; | 1365 | float f; |
1366 | double d; | 1366 | double d; |
1367 | lua_Number n; | 1367 | lua_Number n; |
1368 | char buff[5 * sizeof(lua_Number)]; /* enough for any float type */ | ||
1369 | } Ftypes; | 1368 | } Ftypes; |
1370 | 1369 | ||
1371 | 1370 | ||
@@ -1535,12 +1534,10 @@ static void packint (luaL_Buffer *b, lua_Unsigned n, | |||
1535 | ** Copy 'size' bytes from 'src' to 'dest', correcting endianness if | 1534 | ** Copy 'size' bytes from 'src' to 'dest', correcting endianness if |
1536 | ** given 'islittle' is different from native endianness. | 1535 | ** given 'islittle' is different from native endianness. |
1537 | */ | 1536 | */ |
1538 | static void copywithendian (volatile char *dest, volatile const char *src, | 1537 | static void copywithendian (char *dest, const char *src, |
1539 | int size, int islittle) { | 1538 | int size, int islittle) { |
1540 | if (islittle == nativeendian.little) { | 1539 | if (islittle == nativeendian.little) |
1541 | while (size-- != 0) | 1540 | memcpy(dest, src, size); |
1542 | *(dest++) = *(src++); | ||
1543 | } | ||
1544 | else { | 1541 | else { |
1545 | dest += size - 1; | 1542 | dest += size - 1; |
1546 | while (size-- != 0) | 1543 | while (size-- != 0) |
@@ -1584,14 +1581,14 @@ static int str_pack (lua_State *L) { | |||
1584 | break; | 1581 | break; |
1585 | } | 1582 | } |
1586 | case Kfloat: { /* floating-point options */ | 1583 | case Kfloat: { /* floating-point options */ |
1587 | volatile Ftypes u; | 1584 | Ftypes u; |
1588 | char *buff = luaL_prepbuffsize(&b, size); | 1585 | char *buff = luaL_prepbuffsize(&b, size); |
1589 | lua_Number n = luaL_checknumber(L, arg); /* get argument */ | 1586 | lua_Number n = luaL_checknumber(L, arg); /* get argument */ |
1590 | if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ | 1587 | if (size == sizeof(u.f)) u.f = (float)n; /* copy it into 'u' */ |
1591 | else if (size == sizeof(u.d)) u.d = (double)n; | 1588 | else if (size == sizeof(u.d)) u.d = (double)n; |
1592 | else u.n = n; | 1589 | else u.n = n; |
1593 | /* move 'u' to final result, correcting endianness if needed */ | 1590 | /* move 'u' to final result, correcting endianness if needed */ |
1594 | copywithendian(buff, u.buff, size, h.islittle); | 1591 | copywithendian(buff, (char *)&u, size, h.islittle); |
1595 | luaL_addsize(&b, size); | 1592 | luaL_addsize(&b, size); |
1596 | break; | 1593 | break; |
1597 | } | 1594 | } |
@@ -1717,9 +1714,9 @@ static int str_unpack (lua_State *L) { | |||
1717 | break; | 1714 | break; |
1718 | } | 1715 | } |
1719 | case Kfloat: { | 1716 | case Kfloat: { |
1720 | volatile Ftypes u; | 1717 | Ftypes u; |
1721 | lua_Number num; | 1718 | lua_Number num; |
1722 | copywithendian(u.buff, data + pos, size, h.islittle); | 1719 | copywithendian((char *)&u, data + pos, size, h.islittle); |
1723 | if (size == sizeof(u.f)) num = (lua_Number)u.f; | 1720 | if (size == sizeof(u.f)) num = (lua_Number)u.f; |
1724 | else if (size == sizeof(u.d)) num = (lua_Number)u.d; | 1721 | else if (size == sizeof(u.d)) num = (lua_Number)u.d; |
1725 | else num = u.n; | 1722 | else num = u.n; |
@@ -1738,7 +1735,7 @@ static int str_unpack (lua_State *L) { | |||
1738 | break; | 1735 | break; |
1739 | } | 1736 | } |
1740 | case Kzstr: { | 1737 | case Kzstr: { |
1741 | size_t len = (int)strlen(data + pos); | 1738 | size_t len = strlen(data + pos); |
1742 | luaL_argcheck(L, pos + len < ld, 2, | 1739 | luaL_argcheck(L, pos + len < ld, 2, |
1743 | "unfinished string for format 'z'"); | 1740 | "unfinished string for format 'z'"); |
1744 | lua_pushlstring(L, data + pos, len); | 1741 | lua_pushlstring(L, data + pos, len); |
diff --git a/src/lua/ltable.c b/src/lua/ltable.c index 5a0d066..38bee1d 100644 --- a/src/lua/ltable.c +++ b/src/lua/ltable.c | |||
@@ -172,11 +172,17 @@ static Node *mainpositionTV (const Table *t, const TValue *key) { | |||
172 | ** be equal to floats. It is assumed that 'eqshrstr' is simply | 172 | ** be equal to floats. It is assumed that 'eqshrstr' is simply |
173 | ** pointer equality, so that short strings are handled in the | 173 | ** pointer equality, so that short strings are handled in the |
174 | ** default case. | 174 | ** default case. |
175 | */ | 175 | ** A true 'deadok' means to accept dead keys as equal to their original |
176 | static int equalkey (const TValue *k1, const Node *n2) { | 176 | ** values, which can only happen if the original key was collectable. |
177 | if (rawtt(k1) != keytt(n2)) /* not the same variants? */ | 177 | ** All dead values are compared in the default case, by pointer |
178 | ** identity. (Note that dead long strings are also compared by | ||
179 | ** identity). | ||
180 | */ | ||
181 | static int equalkey (const TValue *k1, const Node *n2, int deadok) { | ||
182 | if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ | ||
183 | !(deadok && keyisdead(n2) && iscollectable(k1))) | ||
178 | return 0; /* cannot be same key */ | 184 | return 0; /* cannot be same key */ |
179 | switch (ttypetag(k1)) { | 185 | switch (keytt(n2)) { |
180 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: | 186 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: |
181 | return 1; | 187 | return 1; |
182 | case LUA_VNUMINT: | 188 | case LUA_VNUMINT: |
@@ -187,7 +193,7 @@ static int equalkey (const TValue *k1, const Node *n2) { | |||
187 | return pvalue(k1) == pvalueraw(keyval(n2)); | 193 | return pvalue(k1) == pvalueraw(keyval(n2)); |
188 | case LUA_VLCF: | 194 | case LUA_VLCF: |
189 | return fvalue(k1) == fvalueraw(keyval(n2)); | 195 | return fvalue(k1) == fvalueraw(keyval(n2)); |
190 | case LUA_VLNGSTR: | 196 | case ctb(LUA_VLNGSTR): |
191 | return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); | 197 | return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); |
192 | default: | 198 | default: |
193 | return gcvalue(k1) == gcvalueraw(keyval(n2)); | 199 | return gcvalue(k1) == gcvalueraw(keyval(n2)); |
@@ -251,11 +257,12 @@ static unsigned int setlimittosize (Table *t) { | |||
251 | /* | 257 | /* |
252 | ** "Generic" get version. (Not that generic: not valid for integers, | 258 | ** "Generic" get version. (Not that generic: not valid for integers, |
253 | ** which may be in array part, nor for floats with integral values.) | 259 | ** which may be in array part, nor for floats with integral values.) |
260 | ** See explanation about 'deadok' in function 'equalkey'. | ||
254 | */ | 261 | */ |
255 | static const TValue *getgeneric (Table *t, const TValue *key) { | 262 | static const TValue *getgeneric (Table *t, const TValue *key, int deadok) { |
256 | Node *n = mainpositionTV(t, key); | 263 | Node *n = mainpositionTV(t, key); |
257 | for (;;) { /* check whether 'key' is somewhere in the chain */ | 264 | for (;;) { /* check whether 'key' is somewhere in the chain */ |
258 | if (equalkey(key, n)) | 265 | if (equalkey(key, n, deadok)) |
259 | return gval(n); /* that's it */ | 266 | return gval(n); /* that's it */ |
260 | else { | 267 | else { |
261 | int nx = gnext(n); | 268 | int nx = gnext(n); |
@@ -292,7 +299,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key, | |||
292 | if (i - 1u < asize) /* is 'key' inside array part? */ | 299 | if (i - 1u < asize) /* is 'key' inside array part? */ |
293 | return i; /* yes; that's the index */ | 300 | return i; /* yes; that's the index */ |
294 | else { | 301 | else { |
295 | const TValue *n = getgeneric(t, key); | 302 | const TValue *n = getgeneric(t, key, 1); |
296 | if (unlikely(isabstkey(n))) | 303 | if (unlikely(isabstkey(n))) |
297 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ | 304 | luaG_runerror(L, "invalid key to 'next'"); /* key not found */ |
298 | i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ | 305 | i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ |
@@ -730,7 +737,7 @@ const TValue *luaH_getstr (Table *t, TString *key) { | |||
730 | else { /* for long strings, use generic case */ | 737 | else { /* for long strings, use generic case */ |
731 | TValue ko; | 738 | TValue ko; |
732 | setsvalue(cast(lua_State *, NULL), &ko, key); | 739 | setsvalue(cast(lua_State *, NULL), &ko, key); |
733 | return getgeneric(t, &ko); | 740 | return getgeneric(t, &ko, 0); |
734 | } | 741 | } |
735 | } | 742 | } |
736 | 743 | ||
@@ -750,7 +757,7 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
750 | /* else... */ | 757 | /* else... */ |
751 | } /* FALLTHROUGH */ | 758 | } /* FALLTHROUGH */ |
752 | default: | 759 | default: |
753 | return getgeneric(t, key); | 760 | return getgeneric(t, key, 0); |
754 | } | 761 | } |
755 | } | 762 | } |
756 | 763 | ||
diff --git a/src/lua/lua.h b/src/lua/lua.h index b348c14..c9d64d7 100644 --- a/src/lua/lua.h +++ b/src/lua/lua.h | |||
@@ -18,7 +18,7 @@ | |||
18 | 18 | ||
19 | #define LUA_VERSION_MAJOR "5" | 19 | #define LUA_VERSION_MAJOR "5" |
20 | #define LUA_VERSION_MINOR "4" | 20 | #define LUA_VERSION_MINOR "4" |
21 | #define LUA_VERSION_RELEASE "0" | 21 | #define LUA_VERSION_RELEASE "2" |
22 | 22 | ||
23 | #define LUA_VERSION_NUM 504 | 23 | #define LUA_VERSION_NUM 504 |
24 | #define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) | 24 | #define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 0) |
diff --git a/src/lua/luaconf.h b/src/lua/luaconf.h index bdf927e..d9cf18c 100644 --- a/src/lua/luaconf.h +++ b/src/lua/luaconf.h | |||
@@ -37,21 +37,6 @@ | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | /* | 39 | /* |
40 | @@ LUAI_MAXCSTACK defines the maximum depth for nested calls and | ||
41 | ** also limits the maximum depth of other recursive algorithms in | ||
42 | ** the implementation, such as syntactic analysis. A value too | ||
43 | ** large may allow the interpreter to crash (C-stack overflow). | ||
44 | ** The default value seems ok for regular machines, but may be | ||
45 | ** too high for restricted hardware. | ||
46 | ** The test file 'cstack.lua' may help finding a good limit. | ||
47 | ** (It will crash with a limit too high.) | ||
48 | */ | ||
49 | #if !defined(LUAI_MAXCSTACK) | ||
50 | #define LUAI_MAXCSTACK 2000 | ||
51 | #endif | ||
52 | |||
53 | |||
54 | /* | ||
55 | @@ LUA_USE_C89 controls the use of non-ISO-C89 features. | 40 | @@ LUA_USE_C89 controls the use of non-ISO-C89 features. |
56 | ** Define it if you want Lua to avoid the use of a few C99 features | 41 | ** Define it if you want Lua to avoid the use of a few C99 features |
57 | ** or Windows-specific features on Windows. | 42 | ** or Windows-specific features on Windows. |
diff --git a/src/lua/lvm.c b/src/lua/lvm.c index 08681af..aa3b22b 100644 --- a/src/lua/lvm.c +++ b/src/lua/lvm.c | |||
@@ -229,7 +229,7 @@ static int forprep (lua_State *L, StkId ra) { | |||
229 | count /= l_castS2U(-(step + 1)) + 1u; | 229 | count /= l_castS2U(-(step + 1)) + 1u; |
230 | } | 230 | } |
231 | /* store the counter in place of the limit (which won't be | 231 | /* store the counter in place of the limit (which won't be |
232 | needed anymore */ | 232 | needed anymore) */ |
233 | setivalue(plimit, l_castU2S(count)); | 233 | setivalue(plimit, l_castU2S(count)); |
234 | } | 234 | } |
235 | } | 235 | } |
@@ -1092,15 +1092,11 @@ void luaV_finishOp (lua_State *L) { | |||
1092 | #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) | 1092 | #define ProtectNT(exp) (savepc(L), (exp), updatetrap(ci)) |
1093 | 1093 | ||
1094 | /* | 1094 | /* |
1095 | ** Protect code that will finish the loop (returns) or can only raise | 1095 | ** Protect code that can only raise errors. (That is, it cannnot change |
1096 | ** errors. (That is, it will not return to the interpreter main loop | 1096 | ** the stack or hooks.) |
1097 | ** after changing the stack or hooks.) | ||
1098 | */ | 1097 | */ |
1099 | #define halfProtect(exp) (savestate(L,ci), (exp)) | 1098 | #define halfProtect(exp) (savestate(L,ci), (exp)) |
1100 | 1099 | ||
1101 | /* idem, but without changing the stack */ | ||
1102 | #define halfProtectNT(exp) (savepc(L), (exp)) | ||
1103 | |||
1104 | /* 'c' is the limit of live values in the stack */ | 1100 | /* 'c' is the limit of live values in the stack */ |
1105 | #define checkGC(L,c) \ | 1101 | #define checkGC(L,c) \ |
1106 | { luaC_condGC(L, (savepc(L), L->top = (c)), \ | 1102 | { luaC_condGC(L, (savepc(L), L->top = (c)), \ |
@@ -1132,17 +1128,20 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1132 | #if LUA_USE_JUMPTABLE | 1128 | #if LUA_USE_JUMPTABLE |
1133 | #include "ljumptab.h" | 1129 | #include "ljumptab.h" |
1134 | #endif | 1130 | #endif |
1135 | tailcall: | 1131 | startfunc: |
1136 | trap = L->hookmask; | 1132 | trap = L->hookmask; |
1133 | returning: /* trap already set */ | ||
1137 | cl = clLvalue(s2v(ci->func)); | 1134 | cl = clLvalue(s2v(ci->func)); |
1138 | k = cl->p->k; | 1135 | k = cl->p->k; |
1139 | pc = ci->u.l.savedpc; | 1136 | pc = ci->u.l.savedpc; |
1140 | if (trap) { | 1137 | if (trap) { |
1141 | if (cl->p->is_vararg) | 1138 | if (pc == cl->p->code) { /* first instruction (not resuming)? */ |
1142 | trap = 0; /* hooks will start after VARARGPREP instruction */ | 1139 | if (cl->p->is_vararg) |
1143 | else if (pc == cl->p->code) /* first instruction (not resuming)? */ | 1140 | trap = 0; /* hooks will start after VARARGPREP instruction */ |
1144 | luaD_hookcall(L, ci); | 1141 | else /* check 'call' hook */ |
1145 | ci->u.l.trap = 1; /* there may be other hooks */ | 1142 | luaD_hookcall(L, ci); |
1143 | } | ||
1144 | ci->u.l.trap = 1; /* assume trap is on, for now */ | ||
1146 | } | 1145 | } |
1147 | base = ci->func + 1; | 1146 | base = ci->func + 1; |
1148 | /* main loop of interpreter */ | 1147 | /* main loop of interpreter */ |
@@ -1151,7 +1150,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1151 | StkId ra; /* instruction's A register */ | 1150 | StkId ra; /* instruction's A register */ |
1152 | vmfetch(); | 1151 | vmfetch(); |
1153 | lua_assert(base == ci->func + 1); | 1152 | lua_assert(base == ci->func + 1); |
1154 | lua_assert(base <= L->top && L->top < L->stack + L->stacksize); | 1153 | lua_assert(base <= L->top && L->top < L->stack_last); |
1155 | /* invalidate top for instructions not expecting it */ | 1154 | /* invalidate top for instructions not expecting it */ |
1156 | lua_assert(isIT(i) || (cast_void(L->top = base), 1)); | 1155 | lua_assert(isIT(i) || (cast_void(L->top = base), 1)); |
1157 | vmdispatch (GET_OPCODE(i)) { | 1156 | vmdispatch (GET_OPCODE(i)) { |
@@ -1606,24 +1605,32 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1606 | vmbreak; | 1605 | vmbreak; |
1607 | } | 1606 | } |
1608 | vmcase(OP_CALL) { | 1607 | vmcase(OP_CALL) { |
1608 | CallInfo *newci; | ||
1609 | int b = GETARG_B(i); | 1609 | int b = GETARG_B(i); |
1610 | int nresults = GETARG_C(i) - 1; | 1610 | int nresults = GETARG_C(i) - 1; |
1611 | if (b != 0) /* fixed number of arguments? */ | 1611 | if (b != 0) /* fixed number of arguments? */ |
1612 | L->top = ra + b; /* top signals number of arguments */ | 1612 | L->top = ra + b; /* top signals number of arguments */ |
1613 | /* else previous instruction set top */ | 1613 | /* else previous instruction set top */ |
1614 | ProtectNT(luaD_call(L, ra, nresults)); | 1614 | savepc(L); /* in case of errors */ |
1615 | if ((newci = luaD_precall(L, ra, nresults)) == NULL) | ||
1616 | updatetrap(ci); /* C call; nothing else to be done */ | ||
1617 | else { /* Lua call: run function in this same C frame */ | ||
1618 | ci = newci; | ||
1619 | ci->callstatus = 0; /* call re-uses 'luaV_execute' */ | ||
1620 | goto startfunc; | ||
1621 | } | ||
1615 | vmbreak; | 1622 | vmbreak; |
1616 | } | 1623 | } |
1617 | vmcase(OP_TAILCALL) { | 1624 | vmcase(OP_TAILCALL) { |
1618 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ | 1625 | int b = GETARG_B(i); /* number of arguments + 1 (function) */ |
1619 | int nparams1 = GETARG_C(i); | 1626 | int nparams1 = GETARG_C(i); |
1620 | /* delat is virtual 'func' - real 'func' (vararg functions) */ | 1627 | /* delta is virtual 'func' - real 'func' (vararg functions) */ |
1621 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; | 1628 | int delta = (nparams1) ? ci->u.l.nextraargs + nparams1 : 0; |
1622 | if (b != 0) | 1629 | if (b != 0) |
1623 | L->top = ra + b; | 1630 | L->top = ra + b; |
1624 | else /* previous instruction set top */ | 1631 | else /* previous instruction set top */ |
1625 | b = cast_int(L->top - ra); | 1632 | b = cast_int(L->top - ra); |
1626 | savepc(ci); /* some calls here can raise errors */ | 1633 | savepc(ci); /* several calls here can raise errors */ |
1627 | if (TESTARG_k(i)) { | 1634 | if (TESTARG_k(i)) { |
1628 | /* close upvalues from current call; the compiler ensures | 1635 | /* close upvalues from current call; the compiler ensures |
1629 | that there are no to-be-closed variables here, so this | 1636 | that there are no to-be-closed variables here, so this |
@@ -1637,16 +1644,17 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1637 | checkstackGCp(L, 1, ra); | 1644 | checkstackGCp(L, 1, ra); |
1638 | } | 1645 | } |
1639 | if (!ttisLclosure(s2v(ra))) { /* C function? */ | 1646 | if (!ttisLclosure(s2v(ra))) { /* C function? */ |
1640 | luaD_call(L, ra, LUA_MULTRET); /* call it */ | 1647 | luaD_precall(L, ra, LUA_MULTRET); /* call it */ |
1641 | updatetrap(ci); | 1648 | updatetrap(ci); |
1642 | updatestack(ci); /* stack may have been relocated */ | 1649 | updatestack(ci); /* stack may have been relocated */ |
1643 | ci->func -= delta; | 1650 | ci->func -= delta; /* restore 'func' (if vararg) */ |
1644 | luaD_poscall(L, ci, cast_int(L->top - ra)); | 1651 | luaD_poscall(L, ci, cast_int(L->top - ra)); /* finish caller */ |
1645 | return; | 1652 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ |
1653 | goto ret; /* caller returns after the tail call */ | ||
1646 | } | 1654 | } |
1647 | ci->func -= delta; | 1655 | ci->func -= delta; /* restore 'func' (if vararg) */ |
1648 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ | 1656 | luaD_pretailcall(L, ci, ra, b); /* prepare call frame */ |
1649 | goto tailcall; | 1657 | goto startfunc; /* execute the callee */ |
1650 | } | 1658 | } |
1651 | vmcase(OP_RETURN) { | 1659 | vmcase(OP_RETURN) { |
1652 | int n = GETARG_B(i) - 1; /* number of results */ | 1660 | int n = GETARG_B(i) - 1; /* number of results */ |
@@ -1665,12 +1673,15 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1665 | ci->func -= ci->u.l.nextraargs + nparams1; | 1673 | ci->func -= ci->u.l.nextraargs + nparams1; |
1666 | L->top = ra + n; /* set call for 'luaD_poscall' */ | 1674 | L->top = ra + n; /* set call for 'luaD_poscall' */ |
1667 | luaD_poscall(L, ci, n); | 1675 | luaD_poscall(L, ci, n); |
1668 | return; | 1676 | updatetrap(ci); /* 'luaD_poscall' can change hooks */ |
1677 | goto ret; | ||
1669 | } | 1678 | } |
1670 | vmcase(OP_RETURN0) { | 1679 | vmcase(OP_RETURN0) { |
1671 | if (L->hookmask) { | 1680 | if (L->hookmask) { |
1672 | L->top = ra; | 1681 | L->top = ra; |
1673 | halfProtectNT(luaD_poscall(L, ci, 0)); /* no hurry... */ | 1682 | savepc(ci); |
1683 | luaD_poscall(L, ci, 0); /* no hurry... */ | ||
1684 | trap = 1; | ||
1674 | } | 1685 | } |
1675 | else { /* do the 'poscall' here */ | 1686 | else { /* do the 'poscall' here */ |
1676 | int nres = ci->nresults; | 1687 | int nres = ci->nresults; |
@@ -1679,12 +1690,14 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1679 | while (nres-- > 0) | 1690 | while (nres-- > 0) |
1680 | setnilvalue(s2v(L->top++)); /* all results are nil */ | 1691 | setnilvalue(s2v(L->top++)); /* all results are nil */ |
1681 | } | 1692 | } |
1682 | return; | 1693 | goto ret; |
1683 | } | 1694 | } |
1684 | vmcase(OP_RETURN1) { | 1695 | vmcase(OP_RETURN1) { |
1685 | if (L->hookmask) { | 1696 | if (L->hookmask) { |
1686 | L->top = ra + 1; | 1697 | L->top = ra + 1; |
1687 | halfProtectNT(luaD_poscall(L, ci, 1)); /* no hurry... */ | 1698 | savepc(ci); |
1699 | luaD_poscall(L, ci, 1); /* no hurry... */ | ||
1700 | trap = 1; | ||
1688 | } | 1701 | } |
1689 | else { /* do the 'poscall' here */ | 1702 | else { /* do the 'poscall' here */ |
1690 | int nres = ci->nresults; | 1703 | int nres = ci->nresults; |
@@ -1698,7 +1711,13 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
1698 | setnilvalue(s2v(L->top++)); | 1711 | setnilvalue(s2v(L->top++)); |
1699 | } | 1712 | } |
1700 | } | 1713 | } |
1701 | return; | 1714 | ret: /* return from a Lua function */ |
1715 | if (ci->callstatus & CIST_FRESH) | ||
1716 | return; /* end this frame */ | ||
1717 | else { | ||
1718 | ci = ci->previous; | ||
1719 | goto returning; /* continue running caller in this frame */ | ||
1720 | } | ||
1702 | } | 1721 | } |
1703 | vmcase(OP_FORLOOP) { | 1722 | vmcase(OP_FORLOOP) { |
1704 | if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ | 1723 | if (ttisinteger(s2v(ra + 2))) { /* integer loop? */ |
diff --git a/src/lua/makefile b/src/lua/makefile index c4b0064..bf09f24 100644 --- a/src/lua/makefile +++ b/src/lua/makefile | |||
@@ -6,7 +6,6 @@ | |||
6 | 6 | ||
7 | # Warnings valid for both C and C++ | 7 | # Warnings valid for both C and C++ |
8 | CWARNSCPP= \ | 8 | CWARNSCPP= \ |
9 | -fmax-errors=5 \ | ||
10 | -Wextra \ | 9 | -Wextra \ |
11 | -Wshadow \ | 10 | -Wshadow \ |
12 | -Wsign-compare \ | 11 | -Wsign-compare \ |
@@ -15,8 +14,6 @@ CWARNSCPP= \ | |||
15 | -Wredundant-decls \ | 14 | -Wredundant-decls \ |
16 | -Wdisabled-optimization \ | 15 | -Wdisabled-optimization \ |
17 | -Wdouble-promotion \ | 16 | -Wdouble-promotion \ |
18 | -Wlogical-op \ | ||
19 | -Wno-aggressive-loop-optimizations \ | ||
20 | # the next warnings might be useful sometimes, | 17 | # the next warnings might be useful sometimes, |
21 | # but usually they generate too much noise | 18 | # but usually they generate too much noise |
22 | # -Werror \ | 19 | # -Werror \ |