diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-01-25 13:52:52 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-01-25 13:52:52 -0300 |
commit | 108e0bdc8495782544c351b17eaae1411a910e89 (patch) | |
tree | 1196b9d9288b38b0be0290e30ec818fa09d06238 | |
parent | b34a97a4af5c9e973915c07dba918d95009e0acd (diff) | |
parent | e288c5a91883793d14ed9e9d93464f6ee0b08915 (diff) | |
download | lua-108e0bdc8495782544c351b17eaae1411a910e89.tar.gz lua-108e0bdc8495782544c351b17eaae1411a910e89.tar.bz2 lua-108e0bdc8495782544c351b17eaae1411a910e89.zip |
Merge branch 'master' into nextversion
-rw-r--r-- | lauxlib.c | 9 | ||||
-rw-r--r-- | ldebug.c | 5 | ||||
-rw-r--r-- | ldo.c | 4 | ||||
-rw-r--r-- | lstring.c | 2 | ||||
-rw-r--r-- | ltests.c | 5 | ||||
-rw-r--r-- | lvm.c | 2 | ||||
-rw-r--r-- | manual/manual.of | 4 | ||||
-rw-r--r-- | testes/coroutine.lua | 8 |
8 files changed, 27 insertions, 12 deletions
@@ -1043,9 +1043,14 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { | |||
1043 | } | 1043 | } |
1044 | 1044 | ||
1045 | 1045 | ||
1046 | /* | ||
1047 | ** Standard panic funcion just prints an error message. The test | ||
1048 | ** with 'lua_type' avoids possible memory errors in 'lua_tostring'. | ||
1049 | */ | ||
1046 | static int panic (lua_State *L) { | 1050 | static int panic (lua_State *L) { |
1047 | const char *msg = lua_tostring(L, -1); | 1051 | const char *msg = (lua_type(L, -1) == LUA_TSTRING) |
1048 | if (msg == NULL) msg = "error object is not a string"; | 1052 | ? lua_tostring(L, -1) |
1053 | : "error object is not a string"; | ||
1049 | lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", | 1054 | lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n", |
1050 | msg); | 1055 | msg); |
1051 | return 0; /* return to Lua to abort */ | 1056 | return 0; /* return to Lua to abort */ |
@@ -927,12 +927,12 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) { | |||
927 | } | 927 | } |
928 | pc++; /* reference is always next instruction */ | 928 | pc++; /* reference is always next instruction */ |
929 | ci->u.l.savedpc = pc; /* save 'pc' */ | 929 | ci->u.l.savedpc = pc; /* save 'pc' */ |
930 | counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT)); | 930 | counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0); |
931 | if (counthook) | 931 | if (counthook) |
932 | resethookcount(L); /* reset count */ | 932 | resethookcount(L); /* reset count */ |
933 | else if (!(mask & LUA_MASKLINE)) | 933 | else if (!(mask & LUA_MASKLINE)) |
934 | return 1; /* no line hook and count != 0; nothing to be done now */ | 934 | return 1; /* no line hook and count != 0; nothing to be done now */ |
935 | if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */ | 935 | if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */ |
936 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ | 936 | ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */ |
937 | return 1; /* do not call hook again (VM yielded, so it did not move) */ | 937 | return 1; /* do not call hook again (VM yielded, so it did not move) */ |
938 | } | 938 | } |
@@ -954,7 +954,6 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) { | |||
954 | if (L->status == LUA_YIELD) { /* did hook yield? */ | 954 | if (L->status == LUA_YIELD) { /* did hook yield? */ |
955 | if (counthook) | 955 | if (counthook) |
956 | L->hookcount = 1; /* undo decrement to zero */ | 956 | L->hookcount = 1; /* undo decrement to zero */ |
957 | ci->u.l.savedpc--; /* undo increment (resume will increment it again) */ | ||
958 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ | 957 | ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */ |
959 | luaD_throw(L, LUA_YIELD); | 958 | luaD_throw(L, LUA_YIELD); |
960 | } | 959 | } |
@@ -792,6 +792,10 @@ static void resume (lua_State *L, void *ud) { | |||
792 | lua_assert(L->status == LUA_YIELD); | 792 | lua_assert(L->status == LUA_YIELD); |
793 | L->status = LUA_OK; /* mark that it is running (again) */ | 793 | L->status = LUA_OK; /* mark that it is running (again) */ |
794 | if (isLua(ci)) { /* yielded inside a hook? */ | 794 | if (isLua(ci)) { /* yielded inside a hook? */ |
795 | /* undo increment made by 'luaG_traceexec': instruction was not | ||
796 | executed yet */ | ||
797 | lua_assert(ci->callstatus & CIST_HOOKYIELD); | ||
798 | ci->u.l.savedpc--; | ||
795 | L->top.p = firstArg; /* discard arguments */ | 799 | L->top.p = firstArg; /* discard arguments */ |
796 | luaV_execute(L, ci); /* just continue running Lua code */ | 800 | luaV_execute(L, ci); /* just continue running Lua code */ |
797 | } | 801 | } |
@@ -241,7 +241,7 @@ TString *luaS_newlstr (lua_State *L, const char *str, size_t l) { | |||
241 | return internshrstr(L, str, l); | 241 | return internshrstr(L, str, l); |
242 | else { | 242 | else { |
243 | TString *ts; | 243 | TString *ts; |
244 | if (l_unlikely(l >= (MAX_SIZE - sizeof(TString))/sizeof(char))) | 244 | if (l_unlikely(l * sizeof(char) >= (MAX_SIZE - sizeof(TString)))) |
245 | luaM_toobig(L); | 245 | luaM_toobig(L); |
246 | ts = luaS_createlngstrobj(L, l); | 246 | ts = luaS_createlngstrobj(L, l); |
247 | memcpy(getlngstr(ts), str, l * sizeof(char)); | 247 | memcpy(getlngstr(ts), str, l * sizeof(char)); |
@@ -73,8 +73,9 @@ static void badexit (const char *fmt, const char *s1, const char *s2) { | |||
73 | 73 | ||
74 | 74 | ||
75 | static int tpanic (lua_State *L) { | 75 | static int tpanic (lua_State *L) { |
76 | const char *msg = lua_tostring(L, -1); | 76 | const char *msg = (lua_type(L, -1) == LUA_TSTRING) |
77 | if (msg == NULL) msg = "error object is not a string"; | 77 | ? lua_tostring(L, -1) |
78 | : "error object is not a string"; | ||
78 | return (badexit("PANIC: unprotected error in call to Lua API (%s)\n", | 79 | return (badexit("PANIC: unprotected error in call to Lua API (%s)\n", |
79 | msg, NULL), | 80 | msg, NULL), |
80 | 0); /* do not return to Lua */ | 81 | 0); /* do not return to Lua */ |
@@ -655,7 +655,7 @@ void luaV_concat (lua_State *L, int total) { | |||
655 | /* collect total length and number of strings */ | 655 | /* collect total length and number of strings */ |
656 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { | 656 | for (n = 1; n < total && tostring(L, s2v(top - n - 1)); n++) { |
657 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); | 657 | size_t l = tsslen(tsvalue(s2v(top - n - 1))); |
658 | if (l_unlikely(l >= (MAX_SIZE/sizeof(char)) - tl)) { | 658 | if (l_unlikely(l >= MAX_SIZE - sizeof(TString) - tl)) { |
659 | L->top.p = top - total; /* pop strings to avoid wasting stack */ | 659 | L->top.p = top - total; /* pop strings to avoid wasting stack */ |
660 | luaG_runerror(L, "string length overflow"); | 660 | luaG_runerror(L, "string length overflow"); |
661 | } | 661 | } |
diff --git a/manual/manual.of b/manual/manual.of index 42269ff4..e3cbddb3 100644 --- a/manual/manual.of +++ b/manual/manual.of | |||
@@ -4552,6 +4552,10 @@ The pointer returned by @id{lua_tolstring} | |||
4552 | may be invalidated by the garbage collector if the | 4552 | may be invalidated by the garbage collector if the |
4553 | corresponding Lua value is removed from the stack @see{constchar}. | 4553 | corresponding Lua value is removed from the stack @see{constchar}. |
4554 | 4554 | ||
4555 | This function can raise memory errors only | ||
4556 | when converting a number to a string | ||
4557 | (as then it may have to create a new string). | ||
4558 | |||
4555 | } | 4559 | } |
4556 | 4560 | ||
4557 | @APIEntry{lua_Number lua_tonumber (lua_State *L, int index);| | 4561 | @APIEntry{lua_Number lua_tonumber (lua_State *L, int index);| |
diff --git a/testes/coroutine.lua b/testes/coroutine.lua index 6c15db03..664ef5fa 100644 --- a/testes/coroutine.lua +++ b/testes/coroutine.lua | |||
@@ -610,18 +610,20 @@ else | |||
610 | -- (bug in 5.2/5.3) | 610 | -- (bug in 5.2/5.3) |
611 | c = coroutine.create(function (a, ...) | 611 | c = coroutine.create(function (a, ...) |
612 | T.sethook("yield 0", "l") -- will yield on next two lines | 612 | T.sethook("yield 0", "l") -- will yield on next two lines |
613 | assert(a == 10) | 613 | local b = a |
614 | return ... | 614 | return ... |
615 | end) | 615 | end) |
616 | 616 | ||
617 | assert(coroutine.resume(c, 1, 2, 3)) -- start coroutine | 617 | assert(coroutine.resume(c, 1, 2, 3)) -- start coroutine |
618 | local n,v = debug.getlocal(c, 0, 1) -- check its local | 618 | local n,v = debug.getlocal(c, 0, 1) -- check its local |
619 | assert(n == "a" and v == 1) | 619 | assert(n == "a" and v == 1 and debug.getlocal(c, 0, 2) ~= "b") |
620 | assert(debug.setlocal(c, 0, 1, 10)) -- test 'setlocal' | 620 | assert(debug.setlocal(c, 0, 1, 10)) -- test 'setlocal' |
621 | local t = debug.getinfo(c, 0) -- test 'getinfo' | 621 | local t = debug.getinfo(c, 0) -- test 'getinfo' |
622 | assert(t.currentline == t.linedefined + 1) | 622 | assert(t.currentline == t.linedefined + 2) |
623 | assert(not debug.getinfo(c, 1)) -- no other level | 623 | assert(not debug.getinfo(c, 1)) -- no other level |
624 | assert(coroutine.resume(c)) -- run next line | 624 | assert(coroutine.resume(c)) -- run next line |
625 | local n,v = debug.getlocal(c, 0, 2) -- check next local | ||
626 | assert(n == "b" and v == 10) | ||
625 | v = {coroutine.resume(c)} -- finish coroutine | 627 | v = {coroutine.resume(c)} -- finish coroutine |
626 | assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef) | 628 | assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef) |
627 | assert(not coroutine.resume(c)) | 629 | assert(not coroutine.resume(c)) |