diff options
| -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 \ |
