From c197885cb00b85251c35cffdc4057efaee2d7a88 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 15 May 2023 10:20:13 -0300 Subject: Small improvements in tests --- testes/db.lua | 2 +- testes/main.lua | 43 +++++++++++++++++++++++-------------------- 2 files changed, 24 insertions(+), 21 deletions(-) (limited to 'testes') diff --git a/testes/db.lua b/testes/db.lua index 02b96aca..67b58934 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -928,7 +928,7 @@ do local cl = countlines(rest) -- at most 10 lines in first part, 11 in second, plus '...' assert(cl <= 10 + 11 + 1) - local brk = string.find(rest, "%.%.%.") + local brk = string.find(rest, "%.%.%.\t%(skip") if brk then -- does message have '...'? local rest1 = string.sub(rest, 1, brk) local rest2 = string.sub(rest, brk, #rest) diff --git a/testes/main.lua b/testes/main.lua index f59badcf..3fa94e97 100644 --- a/testes/main.lua +++ b/testes/main.lua @@ -27,17 +27,19 @@ do end print("progname: "..progname) -local prepfile = function (s, p) - p = p or prog - io.output(p) - io.write(s) - assert(io.close()) + +local prepfile = function (s, mod, p) + mod = mod and "wb" or "w" -- mod true means binary files + p = p or prog -- file to write the program + local f = io.open(p, mod) + f:write(s) + assert(f:close()) end local function getoutput () - io.input(out) - local t = io.read("a") - io.input():close() + local f = io.open(out) + local t = f:read("a") + f:close() assert(os.remove(out)) return t end @@ -65,10 +67,11 @@ local function RUN (p, ...) assert(os.execute(s)) end + local function NoRun (msg, p, ...) p = string.gsub(p, "lua", '"'..progname..'"', 1) local s = string.format(p, ...) - s = string.format("%s 2> %s", s, out) -- will send error to 'out' + s = string.format("%s >%s 2>&1", s, out) -- send output and error to 'out' assert(not os.execute(s)) assert(string.find(getoutput(), msg, 1, true)) -- check error message end @@ -108,17 +111,17 @@ RUN('lua %s > %s', prog, out) checkout("3\n") -- bad BOMs -prepfile("\xEF") -NoRun("unexpected symbol", 'lua %s > %s', prog, out) +prepfile("\xEF", true) +NoRun("unexpected symbol", 'lua %s', prog) -prepfile("\xEF\xBB") -NoRun("unexpected symbol", 'lua %s > %s', prog, out) +prepfile("\xEF\xBB", true) +NoRun("unexpected symbol", 'lua %s', prog) -prepfile("\xEFprint(3)") -NoRun("unexpected symbol", 'lua %s > %s', prog, out) +prepfile("\xEFprint(3)", true) +NoRun("unexpected symbol", 'lua %s', prog) -prepfile("\xEF\xBBprint(3)") -NoRun("unexpected symbol", 'lua %s > %s', prog, out) +prepfile("\xEF\xBBprint(3)", true) +NoRun("unexpected symbol", 'lua %s', prog) -- test option '-' @@ -213,7 +216,7 @@ convert("a;b;;c") -- test -l over multiple libraries prepfile("print(1); a=2; return {x=15}") -prepfile(("print(a); print(_G['%s'].x)"):format(prog), otherprog) +prepfile(("print(a); print(_G['%s'].x)"):format(prog), false, otherprog) RUN('env LUA_PATH="?;;" lua -l %s -l%s -lstring -l io %s > %s', prog, otherprog, otherprog, out) checkout("1\n2\n15\n2\n15\n") @@ -237,7 +240,7 @@ RUN('lua "-e " -- %s a b c', prog) -- "-e " runs an empty command -- test 'arg' availability in libraries prepfile"assert(arg)" -prepfile("assert(arg)", otherprog) +prepfile("assert(arg)", false, otherprog) RUN('env LUA_PATH="?;;" lua -l%s - < %s', prog, otherprog) -- test messing up the 'arg' table @@ -413,7 +416,7 @@ prepfile[[#comment in 1st line without \n at the end]] RUN('lua %s', prog) -- first-line comment with binary file -prepfile("#comment\n" .. string.dump(load("print(3)"))) +prepfile("#comment\n" .. string.dump(load("print(3)")), true) RUN('lua %s > %s', prog, out) checkout('3\n') -- cgit v1.2.3-55-g6feb From 09f3c2372f5dbeaec9f50614a26c1b5761726a88 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 15 May 2023 13:46:38 -0300 Subject: Option '-l' discards version sufix from file name Like 'require', the command-line option '-l' discards an optional version suffix (everything after an hyphen) from a file name when creating the module name. --- loadlib.c | 9 --------- lua.c | 12 ++++++++++-- luaconf.h | 9 +++++++++ testes/main.lua | 7 +++++++ 4 files changed, 26 insertions(+), 11 deletions(-) (limited to 'testes') diff --git a/loadlib.c b/loadlib.c index d792dffa..6d289fce 100644 --- a/loadlib.c +++ b/loadlib.c @@ -24,15 +24,6 @@ #include "lualib.h" -/* -** LUA_IGMARK is a mark to ignore all before it when building the -** luaopen_ function name. -*/ -#if !defined (LUA_IGMARK) -#define LUA_IGMARK "-" -#endif - - /* ** LUA_CSUBSEP is the character that replaces dots in submodule names ** when searching for a C loader. diff --git a/lua.c b/lua.c index 0ff88454..3af5ce6a 100644 --- a/lua.c +++ b/lua.c @@ -210,12 +210,17 @@ static int dostring (lua_State *L, const char *s, const char *name) { /* ** Receives 'globname[=modname]' and runs 'globname = require(modname)'. +** If there is no explicit modname and globname contains a '-', cut +** the sufix after '-' (the "version") to make the global name. */ static int dolibrary (lua_State *L, char *globname) { int status; + char *suffix = NULL; char *modname = strchr(globname, '='); - if (modname == NULL) /* no explicit name? */ + if (modname == NULL) { /* no explicit name? */ modname = globname; /* module name is equal to global name */ + suffix = strchr(modname, *LUA_IGMARK); /* look for a suffix mark */ + } else { *modname = '\0'; /* global name ends here */ modname++; /* module name starts after the '=' */ @@ -223,8 +228,11 @@ static int dolibrary (lua_State *L, char *globname) { lua_getglobal(L, "require"); lua_pushstring(L, modname); status = docall(L, 1, 1); /* call 'require(modname)' */ - if (status == LUA_OK) + if (status == LUA_OK) { + if (suffix != NULL) /* is there a suffix mark? */ + *suffix = '\0'; /* remove sufix from global name */ lua_setglobal(L, globname); /* globname = require(modname) */ + } return report(L, status); } diff --git a/luaconf.h b/luaconf.h index 137103ed..acebe29c 100644 --- a/luaconf.h +++ b/luaconf.h @@ -257,6 +257,15 @@ #endif + +/* +** LUA_IGMARK is a mark to ignore all after it when building the +** module name (e.g., used to build the luaopen_ function name). +** Typically, the sufix after the mark is the module version, +** as in "mod-v1.2.so". +*/ +#define LUA_IGMARK "-" + /* }================================================================== */ diff --git a/testes/main.lua b/testes/main.lua index 3fa94e97..11b14b44 100644 --- a/testes/main.lua +++ b/testes/main.lua @@ -225,6 +225,13 @@ prepfile("print(str.upper'alo alo', m.max(10, 20))") RUN("lua -l 'str=string' '-lm=math' -e 'print(m.sin(0))' %s > %s", prog, out) checkout("0.0\nALO ALO\t20\n") + +-- test module names with version sufix ("libs/lib2-v2") +RUN("env LUA_CPATH='./libs/?.so' lua -l lib2-v2 -e 'print(lib2.id())' > %s", + out) +checkout("true\n") + + -- test 'arg' table local a = [[ assert(#arg == 3 and arg[1] == 'a' and -- cgit v1.2.3-55-g6feb From cbae01620278f9b568805db16a96d0631ced473d Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Mon, 3 Jul 2023 14:12:54 -0300 Subject: Details --- lundump.h | 3 +-- testes/calls.lua | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) (limited to 'testes') diff --git a/lundump.h b/lundump.h index f3748a99..bc71ced8 100644 --- a/lundump.h +++ b/lundump.h @@ -21,8 +21,7 @@ /* ** Encode major-minor version in one byte, one nibble for each */ -#define MYINT(s) (s[0]-'0') /* assume one-digit numerals */ -#define LUAC_VERSION (MYINT(LUA_VERSION_MAJOR)*16+MYINT(LUA_VERSION_MINOR)) +#define LUAC_VERSION (LUA_VERSION_MAJOR_N*16+LUA_VERSION_MINOR_N) #define LUAC_FORMAT 0 /* this is the official format */ diff --git a/testes/calls.lua b/testes/calls.lua index 2d562a24..664be1b4 100644 --- a/testes/calls.lua +++ b/testes/calls.lua @@ -342,7 +342,7 @@ do -- another bug (in 5.4.0) end -do -- another bug (since 5.2) +if not _port then -- another bug (since 5.2) -- corrupted binary dump: list of upvalue names is larger than number -- of upvalues, overflowing the array of upvalues. local code = -- cgit v1.2.3-55-g6feb From f4211a5ea4e235ccfa8b8dfa46031c23e9e839e2 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 17 Aug 2023 10:42:56 -0300 Subject: More control over encoding of test files The few UTF-8 test files are commented as such, and there is only one non UTF-8 test file (to test non UTF-8 sources). --- testes/db.lua | 6 +++--- testes/files.lua | 8 ++++---- testes/pm.lua | 56 +++++++++++++++++++++++++++++++++++------------------- testes/sort.lua | 2 +- testes/strings.lua | 3 +++ testes/utf8.lua | 2 ++ 6 files changed, 49 insertions(+), 28 deletions(-) (limited to 'testes') diff --git a/testes/db.lua b/testes/db.lua index 67b58934..d3758c41 100644 --- a/testes/db.lua +++ b/testes/db.lua @@ -345,7 +345,7 @@ function f(a,b) local _, y = debug.getlocal(1, 2) assert(x == a and y == b) assert(debug.setlocal(2, 3, "pera") == "AA".."AA") - assert(debug.setlocal(2, 4, "maçã") == "B") + assert(debug.setlocal(2, 4, "manga") == "B") x = debug.getinfo(2) assert(x.func == g and x.what == "Lua" and x.name == 'g' and x.nups == 2 and string.find(x.source, "^@.*db%.lua$")) @@ -373,9 +373,9 @@ function g (...) local arg = {...} do local a,b,c; a=math.sin(40); end local feijao - local AAAA,B = "xuxu", "mamão" + local AAAA,B = "xuxu", "abacate" f(AAAA,B) - assert(AAAA == "pera" and B == "maçã") + assert(AAAA == "pera" and B == "manga") do local B = 13 local x,y = debug.getlocal(1,5) diff --git a/testes/files.lua b/testes/files.lua index be00bf3f..1476006e 100644 --- a/testes/files.lua +++ b/testes/files.lua @@ -92,8 +92,8 @@ assert(io.output():seek("end") == string.len("alo joao")) assert(io.output():seek("set") == 0) -assert(io.write('"álo"', "{a}\n", "second line\n", "third line \n")) -assert(io.write('çfourth_line')) +assert(io.write('"alo"', "{a}\n", "second line\n", "third line \n")) +assert(io.write('Xfourth_line')) io.output(io.stdout) collectgarbage() -- file should be closed by GC assert(io.input() == io.stdin and rawequal(io.output(), io.stdout)) @@ -300,14 +300,14 @@ do -- test error returns end checkerr("invalid format", io.read, "x") assert(io.read(0) == "") -- not eof -assert(io.read(5, 'l') == '"álo"') +assert(io.read(5, 'l') == '"alo"') assert(io.read(0) == "") assert(io.read() == "second line") local x = io.input():seek() assert(io.read() == "third line ") assert(io.input():seek("set", x)) assert(io.read('L') == "third line \n") -assert(io.read(1) == "ç") +assert(io.read(1) == "X") assert(io.read(string.len"fourth_line") == "fourth_line") assert(io.input():seek("cur", -string.len"fourth_line")) assert(io.read() == "fourth_line") diff --git a/testes/pm.lua b/testes/pm.lua index 795596d4..44454dff 100644 --- a/testes/pm.lua +++ b/testes/pm.lua @@ -1,6 +1,9 @@ -- $Id: testes/pm.lua $ -- See Copyright Notice in file all.lua +-- UTF-8 file + + print('testing pattern matching') local function checkerror (msg, f, ...) @@ -50,6 +53,19 @@ assert(f('aLo_ALO', '%a*') == 'aLo') assert(f(" \n\r*&\n\r xuxu \n\n", "%g%g%g+") == "xuxu") + +-- Adapt a pattern to UTF-8 +local function PU (p) + -- break '?' into each individual byte of a character + p = string.gsub(p, "(" .. utf8.charpattern .. ")%?", function (c) + return string.gsub(c, ".", "%0?") + end) + -- change '.' to utf-8 character patterns + p = string.gsub(p, "%.", utf8.charpattern) + return p +end + + assert(f('aaab', 'a*') == 'aaa'); assert(f('aaa', '^.*$') == 'aaa'); assert(f('aaa', 'b*') == ''); @@ -73,16 +89,16 @@ assert(f('aaa', '^.-$') == 'aaa') assert(f('aabaaabaaabaaaba', 'b.*b') == 'baaabaaabaaab') assert(f('aabaaabaaabaaaba', 'b.-b') == 'baaab') assert(f('alo xo', '.o$') == 'xo') -assert(f(' \n isto é assim', '%S%S*') == 'isto') -assert(f(' \n isto é assim', '%S*$') == 'assim') -assert(f(' \n isto é assim', '[a-z]*$') == 'assim') +assert(f(' \n isto é assim', '%S%S*') == 'isto') +assert(f(' \n isto é assim', '%S*$') == 'assim') +assert(f(' \n isto é assim', '[a-z]*$') == 'assim') assert(f('um caracter ? extra', '[^%sa-z]') == '?') assert(f('', 'a?') == '') -assert(f('á', 'á?') == 'á') -assert(f('ábl', 'á?b?l?') == 'ábl') -assert(f(' ábl', 'á?b?l?') == '') +assert(f('á', PU'á?') == 'á') +assert(f('ábl', PU'á?b?l?') == 'ábl') +assert(f(' ábl', PU'á?b?l?') == '') assert(f('aa', '^aa?a?a') == 'aa') -assert(f(']]]áb', '[^]]') == 'á') +assert(f(']]]áb', '[^]]+') == 'áb') assert(f("0alo alo", "%x*") == "0a") assert(f("alo alo", "%C+") == "alo alo") print('+') @@ -136,28 +152,28 @@ assert(string.match("alo xyzK", "(%w+)K") == "xyz") assert(string.match("254 K", "(%d*)K") == "") assert(string.match("alo ", "(%w*)$") == "") assert(not string.match("alo ", "(%w+)$")) -assert(string.find("(álo)", "%(á") == 1) -local a, b, c, d, e = string.match("âlo alo", "^(((.).).* (%w*))$") -assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) +assert(string.find("(álo)", "%(á") == 1) +local a, b, c, d, e = string.match("âlo alo", PU"^(((.).). (%w*))$") +assert(a == 'âlo alo' and b == 'âl' and c == 'â' and d == 'alo' and e == nil) a, b, c, d = string.match('0123456789', '(.+(.?)())') assert(a == '0123456789' and b == '' and c == 11 and d == nil) print('+') -assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo') -assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim +assert(string.gsub('ülo ülo', 'ü', 'x') == 'xlo xlo') +assert(string.gsub('alo úlo ', ' +$', '') == 'alo úlo') -- trim assert(string.gsub(' alo alo ', '^%s*(.-)%s*$', '%1') == 'alo alo') -- double trim assert(string.gsub('alo alo \n 123\n ', '%s+', ' ') == 'alo alo 123 ') -local t = "abç d" -a, b = string.gsub(t, '(.)', '%1@') -assert('@'..a == string.gsub(t, '', '@') and b == 5) -a, b = string.gsub('abçd', '(.)', '%0@', 2) -assert(a == 'a@b@çd' and b == 2) +local t = "abç d" +a, b = string.gsub(t, PU'(.)', '%1@') +assert(a == "a@b@ç@ @d@" and b == 5) +a, b = string.gsub('abçd', PU'(.)', '%0@', 2) +assert(a == 'a@b@çd' and b == 2) assert(string.gsub('alo alo', '()[al]', '%1') == '12o 56o') assert(string.gsub("abc=xyz", "(%w*)(%p)(%w+)", "%3%2%1-%0") == "xyz=abc-abc=xyz") assert(string.gsub("abc", "%w", "%1%0") == "aabbcc") assert(string.gsub("abc", "%w+", "%0%1") == "abcabc") -assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú') +assert(string.gsub('áéí', '$', '\0óú') == 'áéí\0óú') assert(string.gsub('', '^', 'r') == 'r') assert(string.gsub('', '$', 'r') == 'r') print('+') @@ -188,8 +204,8 @@ do end function f(a,b) return string.gsub(a,'.',b) end -assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) == - "trocar tudo em bbbbb é alalalalalal") +assert(string.gsub("trocar tudo em |teste|b| é |beleza|al|", "|([^|]*)|([^|]*)|", f) == + "trocar tudo em bbbbb é alalalalalal") local function dostring (s) return load(s, "")() or "" end assert(string.gsub("alo $a='x'$ novamente $return a$", diff --git a/testes/sort.lua b/testes/sort.lua index 52919b8c..40bb2d8a 100644 --- a/testes/sort.lua +++ b/testes/sort.lua @@ -289,7 +289,7 @@ timesort(a, limit, function(x,y) return nil end, "equal") for i,v in pairs(a) do assert(v == false) end -AA = {"álo", "\0first :-)", "alo", "then this one", "45", "and a new"} +AA = {"\xE1lo", "\0first :-)", "alo", "then this one", "45", "and a new"} table.sort(AA) check(AA) diff --git a/testes/strings.lua b/testes/strings.lua index b033c6ab..90983edd 100644 --- a/testes/strings.lua +++ b/testes/strings.lua @@ -1,6 +1,9 @@ -- $Id: testes/strings.lua $ -- See Copyright Notice in file all.lua +-- ISO Latin encoding + + print('testing strings and string library') local maxi = math.maxinteger diff --git a/testes/utf8.lua b/testes/utf8.lua index c5a9dd3f..efadbd5c 100644 --- a/testes/utf8.lua +++ b/testes/utf8.lua @@ -1,6 +1,8 @@ -- $Id: testes/utf8.lua $ -- See Copyright Notice in file all.lua +-- UTF-8 file + print "testing UTF-8 library" local utf8 = require'utf8' -- cgit v1.2.3-55-g6feb From 5ab6a5756b3c50c99f1388885e9a48a7da8cbe2d Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 23 Aug 2023 13:49:27 -0300 Subject: Bug: Wrong line number for function calls --- lparser.c | 12 ++++++------ testes/errors.lua | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'testes') diff --git a/lparser.c b/lparser.c index b745f236..2b888c7c 100644 --- a/lparser.c +++ b/lparser.c @@ -1022,10 +1022,11 @@ static int explist (LexState *ls, expdesc *v) { } -static void funcargs (LexState *ls, expdesc *f, int line) { +static void funcargs (LexState *ls, expdesc *f) { FuncState *fs = ls->fs; expdesc args; int base, nparams; + int line = ls->linenumber; switch (ls->t.token) { case '(': { /* funcargs -> '(' [ explist ] ')' */ luaX_next(ls); @@ -1063,8 +1064,8 @@ static void funcargs (LexState *ls, expdesc *f, int line) { } init_exp(f, VCALL, luaK_codeABC(fs, OP_CALL, base, nparams+1, 2)); luaK_fixline(fs, line); - fs->freereg = base+1; /* call remove function and arguments and leaves - (unless changed) one result */ + fs->freereg = base+1; /* call removes function and arguments and leaves + one result (unless changed later) */ } @@ -1103,7 +1104,6 @@ static void suffixedexp (LexState *ls, expdesc *v) { /* suffixedexp -> primaryexp { '.' NAME | '[' exp ']' | ':' NAME funcargs | funcargs } */ FuncState *fs = ls->fs; - int line = ls->linenumber; primaryexp(ls, v); for (;;) { switch (ls->t.token) { @@ -1123,12 +1123,12 @@ static void suffixedexp (LexState *ls, expdesc *v) { luaX_next(ls); codename(ls, &key); luaK_self(fs, v, &key); - funcargs(ls, v, line); + funcargs(ls, v); break; } case '(': case TK_STRING: case '{': { /* funcargs */ luaK_exp2nextreg(fs, v); - funcargs(ls, v, line); + funcargs(ls, v); break; } default: return; diff --git a/testes/errors.lua b/testes/errors.lua index bf6f389d..b777a329 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -392,19 +392,19 @@ lineerror("a\n=\n-\n\nprint\n;", 3) lineerror([[ a -( +( -- << 23) -]], 1) +]], 2) lineerror([[ local a = {x = 13} a . x -( +( -- << 23 ) -]], 2) +]], 5) lineerror([[ local a = {x = 13} -- cgit v1.2.3-55-g6feb From 6baee9ef9d5657ab582c8a4b9f885ec58ed502d0 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Fri, 8 Sep 2023 16:19:21 -0300 Subject: Removed test for "corrupted binary dump" Test is too non portable. (For instance, it does not work for different number types.) --- lundump.c | 2 +- testes/calls.lua | 14 -------------- 2 files changed, 1 insertion(+), 15 deletions(-) (limited to 'testes') diff --git a/lundump.c b/lundump.c index f1852c35..e8d92a85 100644 --- a/lundump.c +++ b/lundump.c @@ -81,7 +81,7 @@ static size_t loadUnsigned (LoadState *S, size_t limit) { static size_t loadSize (LoadState *S) { - return loadUnsigned(S, ~(size_t)0); + return loadUnsigned(S, MAX_SIZET); } diff --git a/testes/calls.lua b/testes/calls.lua index 664be1b4..a1938584 100644 --- a/testes/calls.lua +++ b/testes/calls.lua @@ -342,20 +342,6 @@ do -- another bug (in 5.4.0) end -if not _port then -- another bug (since 5.2) - -- corrupted binary dump: list of upvalue names is larger than number - -- of upvalues, overflowing the array of upvalues. - local code = - "\x1b\x4c\x75\x61\x54\x00\x19\x93\x0d\x0a\x1a\x0a\x04\x08\x08\x78\x56\z - \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x28\x77\x40\x00\x86\x40\z - \x74\x65\x6d\x70\x81\x81\x01\x00\x02\x82\x48\x00\x02\x00\xc7\x00\x01\z - \x00\x80\x80\x80\x82\x00\x00\x80\x81\x82\x78\x80\x82\x81\x86\x40\x74\z - \x65\x6d\x70" - - assert(load(code)) -- segfaults in previous versions -end - - x = string.dump(load("x = 1; return x")) a = assert(load(read1(x), nil, "b")) assert(a() == 1 and _G.x == 1) -- cgit v1.2.3-55-g6feb From 7923dbbf72da303ca1cca17efd24725668992f15 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Wed, 1 Nov 2023 12:00:54 -0300 Subject: Bug: Recursion in 'getobjname' can stack overflow 'getobjname' now broken in two, a basic version that handles locals, upvalues, and constants, and a full version, which uses the basic version to handle table accesses (globals and fields). --- ldebug.c | 153 ++++++++++++++++++++++++++++++------------------------ testes/errors.lua | 3 ++ 2 files changed, 87 insertions(+), 69 deletions(-) (limited to 'testes') diff --git a/ldebug.c b/ldebug.c index 690ac38f..b1f16ac9 100644 --- a/ldebug.c +++ b/ldebug.c @@ -417,40 +417,6 @@ LUA_API int lua_getinfo (lua_State *L, const char *what, lua_Debug *ar) { ** ======================================================= */ -static const char *getobjname (const Proto *p, int lastpc, int reg, - const char **name); - - -/* -** Find a "name" for the constant 'c'. -*/ -static void kname (const Proto *p, int c, const char **name) { - TValue *kvalue = &p->k[c]; - *name = (ttisstring(kvalue)) ? getstr(tsvalue(kvalue)) : "?"; -} - - -/* -** Find a "name" for the register 'c'. -*/ -static void rname (const Proto *p, int pc, int c, const char **name) { - const char *what = getobjname(p, pc, c, name); /* search for 'c' */ - if (!(what && *what == 'c')) /* did not find a constant name? */ - *name = "?"; -} - - -/* -** Find a "name" for a 'C' value in an RK instruction. -*/ -static void rkname (const Proto *p, int pc, Instruction i, const char **name) { - int c = GETARG_C(i); /* key index */ - if (GETARG_k(i)) /* is 'c' a constant? */ - kname(p, c, name); - else /* 'c' is a register */ - rname(p, pc, c, name); -} - static int filterpc (int pc, int jmptarget) { if (pc < jmptarget) /* is code conditional (inside a jump)? */ @@ -509,28 +475,29 @@ static int findsetreg (const Proto *p, int lastpc, int reg) { /* -** Check whether table being indexed by instruction 'i' is the -** environment '_ENV' +** Find a "name" for the constant 'c'. */ -static const char *gxf (const Proto *p, int pc, Instruction i, int isup) { - int t = GETARG_B(i); /* table index */ - const char *name; /* name of indexed variable */ - if (isup) /* is an upvalue? */ - name = upvalname(p, t); - else - getobjname(p, pc, t, &name); - return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; +static const char *kname (const Proto *p, int index, const char **name) { + TValue *kvalue = &p->k[index]; + if (ttisstring(kvalue)) { + *name = getstr(tsvalue(kvalue)); + return "constant"; + } + else { + *name = "?"; + return NULL; + } } -static const char *getobjname (const Proto *p, int lastpc, int reg, - const char **name) { - int pc; - *name = luaF_getlocalname(p, reg + 1, lastpc); +static const char *basicgetobjname (const Proto *p, int *ppc, int reg, + const char **name) { + int pc = *ppc; + *name = luaF_getlocalname(p, reg + 1, pc); if (*name) /* is a local? */ return "local"; /* else try symbolic execution */ - pc = findsetreg(p, lastpc, reg); + *ppc = pc = findsetreg(p, pc, reg); if (pc != -1) { /* could find instruction? */ Instruction i = p->code[pc]; OpCode op = GET_OPCODE(i); @@ -538,18 +505,80 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, case OP_MOVE: { int b = GETARG_B(i); /* move from 'b' to 'a' */ if (b < GETARG_A(i)) - return getobjname(p, pc, b, name); /* get name for 'b' */ + return basicgetobjname(p, ppc, b, name); /* get name for 'b' */ break; } + case OP_GETUPVAL: { + *name = upvalname(p, GETARG_B(i)); + return "upvalue"; + } + case OP_LOADK: return kname(p, GETARG_Bx(i), name); + case OP_LOADKX: return kname(p, GETARG_Ax(p->code[pc + 1]), name); + default: break; + } + } + return NULL; /* could not find reasonable name */ +} + + +/* +** Find a "name" for the register 'c'. +*/ +static void rname (const Proto *p, int pc, int c, const char **name) { + const char *what = basicgetobjname(p, &pc, c, name); /* search for 'c' */ + if (!(what && *what == 'c')) /* did not find a constant name? */ + *name = "?"; +} + + +/* +** Find a "name" for a 'C' value in an RK instruction. +*/ +static void rkname (const Proto *p, int pc, Instruction i, const char **name) { + int c = GETARG_C(i); /* key index */ + if (GETARG_k(i)) /* is 'c' a constant? */ + kname(p, c, name); + else /* 'c' is a register */ + rname(p, pc, c, name); +} + + +/* +** Check whether table being indexed by instruction 'i' is the +** environment '_ENV' +*/ +static const char *isEnv (const Proto *p, int pc, Instruction i, int isup) { + int t = GETARG_B(i); /* table index */ + const char *name; /* name of indexed variable */ + if (isup) /* is 't' an upvalue? */ + name = upvalname(p, t); + else /* 't' is a register */ + basicgetobjname(p, &pc, t, &name); + return (name && strcmp(name, LUA_ENV) == 0) ? "global" : "field"; +} + + +/* +** Extend 'basicgetobjname' to handle table accesses +*/ +static const char *getobjname (const Proto *p, int lastpc, int reg, + const char **name) { + const char *kind = basicgetobjname(p, &lastpc, reg, name); + if (kind != NULL) + return kind; + else if (lastpc != -1) { /* could find instruction? */ + Instruction i = p->code[lastpc]; + OpCode op = GET_OPCODE(i); + switch (op) { case OP_GETTABUP: { int k = GETARG_C(i); /* key index */ kname(p, k, name); - return gxf(p, pc, i, 1); + return isEnv(p, lastpc, i, 1); } case OP_GETTABLE: { int k = GETARG_C(i); /* key index */ - rname(p, pc, k, name); - return gxf(p, pc, i, 0); + rname(p, lastpc, k, name); + return isEnv(p, lastpc, i, 0); } case OP_GETI: { *name = "integer index"; @@ -558,24 +587,10 @@ static const char *getobjname (const Proto *p, int lastpc, int reg, case OP_GETFIELD: { int k = GETARG_C(i); /* key index */ kname(p, k, name); - return gxf(p, pc, i, 0); - } - case OP_GETUPVAL: { - *name = upvalname(p, GETARG_B(i)); - return "upvalue"; - } - case OP_LOADK: - case OP_LOADKX: { - int b = (op == OP_LOADK) ? GETARG_Bx(i) - : GETARG_Ax(p->code[pc + 1]); - if (ttisstring(&p->k[b])) { - *name = getstr(tsvalue(&p->k[b])); - return "constant"; - } - break; + return isEnv(p, lastpc, i, 0); } case OP_SELF: { - rkname(p, pc, i, name); + rkname(p, lastpc, i, name); return "method"; } default: break; /* go through to return NULL */ diff --git a/testes/errors.lua b/testes/errors.lua index b777a329..01cfe906 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -121,6 +121,9 @@ assert(not string.find(doit"aaa={13}; local bbbb=1; aaa[bbbb](3)", "'bbbb'")) checkmessage("aaa={13}; local bbbb=1; aaa[bbbb](3)", "number") checkmessage("aaa=(1)..{}", "a table value") +-- bug in 5.4.6 +checkmessage("a = {_ENV = {}}; print(a._ENV.x + 1)", "field 'x'") + _G.aaa, _G.bbbb = nil -- calls -- cgit v1.2.3-55-g6feb