Merge pull request #34 from walterschell/v5.4.7

Updated to v5.4.7
This commit is contained in:
Walter Schell 2024-09-11 09:13:52 -04:00 committed by GitHub
commit 52674cd192
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
123 changed files with 558 additions and 382 deletions

View File

@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.1)
project(lua LANGUAGES C VERSION 5.4.6)
project(lua LANGUAGES C VERSION 5.4.7)
option(LUA_SUPPORT_DL "Support dynamic loading of compiled modules" OFF)
option(LUA_BUILD_AS_CXX "Build lua as C++" OFF)

View File

@ -1,5 +1,5 @@
# Lua
CMake based build of Lua 5.4.6
CMake based build of Lua 5.4.7
| Build as C | Build as C++ |
| --: | --: |
| ![Build Linux](https://github.com/walterschell/Lua/actions/workflows/build-linux.yml/badge.svg?branch=master) | ![Build Linux as C++](https://github.com/walterschell/Lua/actions/workflows/build-linux-cxx.yml/badge.svg?branch=master) |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.7 KiB

View File

@ -342,20 +342,6 @@ do -- another bug (in 5.4.0)
end
do -- 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)

View File

@ -610,18 +610,20 @@ else
-- (bug in 5.2/5.3)
c = coroutine.create(function (a, ...)
T.sethook("yield 0", "l") -- will yield on next two lines
assert(a == 10)
local b = a
return ...
end)
assert(coroutine.resume(c, 1, 2, 3)) -- start coroutine
local n,v = debug.getlocal(c, 0, 1) -- check its local
assert(n == "a" and v == 1)
assert(n == "a" and v == 1 and debug.getlocal(c, 0, 2) ~= "b")
assert(debug.setlocal(c, 0, 1, 10)) -- test 'setlocal'
local t = debug.getinfo(c, 0) -- test 'getinfo'
assert(t.currentline == t.linedefined + 1)
assert(t.currentline == t.linedefined + 2)
assert(not debug.getinfo(c, 1)) -- no other level
assert(coroutine.resume(c)) -- run next line
local n,v = debug.getlocal(c, 0, 2) -- check next local
assert(n == "b" and v == 10)
v = {coroutine.resume(c)} -- finish coroutine
assert(v[1] == true and v[2] == 2 and v[3] == 3 and v[4] == undef)
assert(not coroutine.resume(c))

View File

@ -49,6 +49,15 @@ do
end
-- bug in 5.4.4-5.4.6: activelines in vararg functions
-- without debug information
do
local func = load(string.dump(load("print(10)"), true))
local actl = debug.getinfo(func, "L").activelines
assert(#actl == 0) -- no line info
end
-- test file and string names truncation
local a = "function f () end"
local function dostring (s, x) return load(s, x)() end
@ -345,7 +354,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 +382,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)
@ -928,7 +937,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)

View File

@ -91,7 +91,7 @@ end
if not T then
(Message or print)
('\n >>> testC not active: skipping memory message test <<<\n')
('\n >>> testC not active: skipping tests for messages in C <<<\n')
else
print "testing memory error message"
local a = {}
@ -104,6 +104,19 @@ else
end)
T.totalmem(0)
assert(not st and msg == "not enough" .. " memory")
-- stack space for luaL_traceback (bug in 5.4.6)
local res = T.testC[[
# push 16 elements on the stack
pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
pushnum 1; pushnum 1; pushnum 1; pushnum 1; pushnum 1;
pushnum 1;
# traceback should work with 4 remaining slots
traceback xuxu 1;
return 1
]]
assert(string.find(res, "xuxu.-main chunk"))
end
@ -121,6 +134,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
@ -392,19 +408,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}

View File

@ -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")

View File

@ -73,8 +73,9 @@ static void badexit (const char *fmt, const char *s1, const char *s2) {
static int tpanic (lua_State *L) {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) msg = "error object is not a string";
const char *msg = (lua_type(L, -1) == LUA_TSTRING)
? lua_tostring(L, -1)
: "error object is not a string";
return (badexit("PANIC: unprotected error in call to Lua API (%s)\n",
msg, NULL),
0); /* do not return to Lua */
@ -1649,6 +1650,11 @@ static int runC (lua_State *L, lua_State *L1, const char *pc) {
int nres;
status = lua_resume(lua_tothread(L1, i), L, getnum, &nres);
}
else if EQ("traceback") {
const char *msg = getstring;
int level = getnum;
luaL_traceback(L1, L1, msg, level);
}
else if EQ("return") {
int n = getnum;
if (L1 != L) {

View File

@ -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")
@ -222,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
@ -237,7 +247,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 +423,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')

View File

@ -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,20 @@ 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)
-- reapply '?' into each individual byte of a character.
-- (For instance, "á?" becomes "\195?\161?".)
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 +90,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 +153,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 +205,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$",

View File

@ -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)

View File

@ -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 <const> = math.maxinteger

View File

@ -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'

View File

@ -46,7 +46,7 @@ TO_MAN= lua.1 luac.1
# Lua version and release.
V= 5.4
R= $V.6
R= $V.7
# Targets start here.
all: $(PLAT)

View File

@ -1,5 +1,5 @@
This is Lua 5.4.6, released on 02 May 2023.
This is Lua 5.4.7, released on 13 Jun 2024.
For installation instructions, license details, and
further information about Lua, see doc/readme.html.

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -10,7 +10,7 @@
<BODY>
<H1>
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
<A HREF="https://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
Lua 5.4 Reference Manual
</H1>
@ -18,7 +18,7 @@ Lua 5.4 Reference Manual
The reference manual is the official definition of the Lua language.
<BR>
For a complete introduction to Lua programming, see the book
<A HREF="http://www.lua.org/pil/">Programming in Lua</A>.
<A HREF="https://www.lua.org/pil/">Programming in Lua</A>.
<DIV CLASS="menubar">
<A HREF="manual.html">start</A>
@ -27,14 +27,14 @@ For a complete introduction to Lua programming, see the book
&middot;
<A HREF="#index">index</A>
&middot;
<A HREF="http://www.lua.org/manual/">other versions</A>
<A HREF="https://www.lua.org/manual/">other versions</A>
</DIV>
<P>
<SMALL>
Copyright &copy; 2020&ndash;2023 Lua.org, PUC-Rio.
Copyright &copy; 2020&ndash;2024 Lua.org, PUC-Rio.
Freely available under the terms of the
<A HREF="http://www.lua.org/license.html">Lua license</A>.
<A HREF="https://www.lua.org/license.html">Lua license</A>.
</SMALL>
<H2><A NAME="contents">Contents</A></H2>
@ -668,10 +668,10 @@ Freely available under the terms of the
<P CLASS="footer">
Last update:
Sat Apr 1 17:57:05 UTC 2023
Thu May 9 14:47:09 UTC 2024
</P>
<!--
Last change: revised for Lua 5.4.5
Last change: revised for Lua 5.4.7
-->
</BODY>

View File

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

View File

@ -1,5 +1,5 @@
.\" $Id: lua.man,v 1.14 2022/09/23 09:06:36 lhf Exp $
.TH LUA 1 "$Date: 2022/09/23 09:06:36 $"
.\" $Id: lua.man,v 1.14 2024/05/08 18:48:27 lhf Exp $
.TH LUA 1 "$Date: 2024/05/08 18:48:27 $"
.SH NAME
lua \- Lua interpreter
.SH SYNOPSIS
@ -123,7 +123,7 @@ and the version-neutral variants are ignored.
Code to be executed before command line options and scripts.
.TP
.B LUA_PATH, LUA_PATH_5_4
Initial value of package.cpath,
Initial value of package.path,
the path used by require to search for Lua loaders.
.TP
.B LUA_CPATH, LUA_CPATH_5_4

View File

@ -143,6 +143,7 @@ table.book td.cover {
table.book img {
border: solid #000080 1px ;
border-radius: 2px ;
}
table.book span {

View File

@ -10,7 +10,7 @@
<BODY>
<H1>
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
<A HREF="https://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
Lua 5.4 Reference Manual
</H1>
@ -19,9 +19,9 @@ by Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes
<P>
<SMALL>
Copyright &copy; 2020&ndash;2023 Lua.org, PUC-Rio.
Copyright &copy; 2020&ndash;2024 Lua.org, PUC-Rio.
Freely available under the terms of the
<a href="http://www.lua.org/license.html">Lua license</a>.
<a href="https://www.lua.org/license.html">Lua license</a>.
</SMALL>
<DIV CLASS="menubar">
@ -29,7 +29,7 @@ Freely available under the terms of the
&middot;
<A HREF="contents.html#index">index</A>
&middot;
<A HREF="http://www.lua.org/manual/">other versions</A>
<A HREF="https://www.lua.org/manual/">other versions</A>
</DIV>
<!-- ====================================================================== -->
@ -391,7 +391,7 @@ Whenever there is an error,
an <em>error object</em>
is propagated with information about the error.
Lua itself only generates errors whose error object is a string,
but programs may generate errors with
but programs can generate errors with
any value as the error object.
It is up to the Lua program or its host to handle such error objects.
For historical reasons,
@ -401,7 +401,7 @@ even though it does not have to be a string.
<p>
When you use <a href="#pdf-xpcall"><code>xpcall</code></a> (or <a href="#lua_pcall"><code>lua_pcall</code></a>, in C)
you may give a <em>message handler</em>
you can give a <em>message handler</em>
to be called in case of errors.
This function is called with the original error object
and returns a new error object.
@ -453,7 +453,7 @@ which is then called a <em>metamethod</em>.
In the previous example, the key is the string "<code>__add</code>"
and the metamethod is the function that performs the addition.
Unless stated otherwise,
a metamethod may in fact be any callable value,
a metamethod can in fact be any callable value,
which is either a function or a value with a <code>__call</code> metamethod.
@ -1725,7 +1725,7 @@ labels in Lua are considered statements too:
<p>
A label is visible in the entire block where it is defined,
except inside nested functions.
A goto may jump to any visible label as long as it does not
A goto can jump to any visible label as long as it does not
enter into the scope of a local variable.
A label should not be declared
where a label with the same name is visible,
@ -5571,7 +5571,7 @@ otherwise, returns <code>NULL</code>.
<hr><h3><a name="lua_toclose"><code>lua_toclose</code></a></h3><p>
<span class="apii">[-0, +0, <em>m</em>]</span>
<span class="apii">[-0, +0, <em>v</em>]</span>
<pre>void lua_toclose (lua_State *L, int index);</pre>
<p>
@ -5591,6 +5591,11 @@ by any other function in the API except <a href="#lua_settop"><code>lua_settop</
unless previously deactivated by <a href="#lua_closeslot"><code>lua_closeslot</code></a>.
<p>
This function raises an error if the value at the given slot
neither has a <code>__close</code> metamethod nor is a false value.
<p>
This function should not be called for an index
that is equal to or below an active to-be-closed slot.
@ -5664,6 +5669,12 @@ after its last character (as in&nbsp;C),
but can contain other zeros in its body.
<p>
This function can raise memory errors only
when converting a number to a string
(as then it may create a new string).
@ -11276,13 +11287,13 @@ The returned table can contain all the fields returned by <a href="#lua_getinfo"
with the string <code>what</code> describing which fields to fill in.
The default for <code>what</code> is to get all information available,
except the table of valid lines.
If present,
the option '<code>f</code>'
The option '<code>f</code>'
adds a field named <code>func</code> with the function itself.
If present,
the option '<code>L</code>'
adds a field named <code>activelines</code> with the table of
valid lines.
The option '<code>L</code>' adds a field named <code>activelines</code>
with the table of valid lines,
provided the function is a Lua function.
If the function has no debug information,
the table is empty.
<p>
@ -11619,6 +11630,10 @@ Lua does not consult any environment variables.
In particular,
the values of <a href="#pdf-package.path"><code>package.path</code></a> and <a href="#pdf-package.cpath"><code>package.cpath</code></a>
are set with the default paths defined in <code>luaconf.h</code>.
To signal to the libraries that this option is on,
the stand-alone interpreter sets the field
<code>"LUA_NOENV"</code> in the registry to a true value.
Other libraries may consult this field for the same purpose.
<p>
@ -12033,13 +12048,12 @@ and LiteralString, see <a href="#3.1">&sect;3.1</a>.)
<P CLASS="footer">
Last update:
Tue May 2 20:09:38 UTC 2023
Thu Jun 13 22:15:52 UTC 2024
</P>
<!--
Last change: revised for Lua 5.4.6
Last change: revised for Lua 5.4.7
-->
</body></html>

View File

@ -29,7 +29,7 @@ tt, kbd, code {
<BODY>
<H1>
<A HREF="http://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
<A HREF="https://www.lua.org/"><IMG SRC="logo.gif" ALT="Lua"></A>
Welcome to Lua 5.4
</H1>
@ -49,29 +49,31 @@ Welcome to Lua 5.4
<P>
Lua is a powerful, efficient, lightweight, embeddable scripting language
developed by a
<A HREF="http://www.lua.org/authors.html">team</A>
<A HREF="https://www.lua.org/authors.html">team</A>
at
<A HREF="http://www.puc-rio.br/">PUC-Rio</A>,
<A HREF="https://www.puc-rio.br/">PUC-Rio</A>,
the Pontifical Catholic University of Rio de Janeiro in Brazil.
Lua is
<A HREF="#license">free software</A>
used in
<A HREF="http://www.lua.org/uses.html">many products and projects</A>
<A HREF="https://www.lua.org/uses.html">many products and projects</A>
around the world.
<P>
Lua's
<A HREF="http://www.lua.org/">official web site</A>
<A HREF="https://www.lua.org/">official website</A>
provides complete information
about Lua,
including
an
<A HREF="http://www.lua.org/about.html">executive summary</A>
<A HREF="https://www.lua.org/about.html">executive summary</A>,
tips on
<A HREF="https://www.lua.org/start.html">getting started</A>,
and
updated
<A HREF="http://www.lua.org/docs.html">documentation</A>,
<A HREF="https://www.lua.org/docs.html">documentation</A>,
especially the
<A HREF="http://www.lua.org/manual/5.4/">reference manual</A>,
<A HREF="https://www.lua.org/manual/5.4/">reference manual</A>,
which may differ slightly from the
<A HREF="contents.html">local copy</A>
distributed in this package.
@ -79,7 +81,7 @@ distributed in this package.
<H2><A NAME="install">Installing Lua</A></H2>
<P>
Lua is distributed in
<A HREF="http://www.lua.org/ftp/">source</A>
<A HREF="https://www.lua.org/ftp/">source</A>
form.
You need to build it before using it.
Building Lua should be straightforward
@ -88,7 +90,7 @@ Lua is implemented in pure ANSI C and compiles unmodified in all known
platforms that have an ANSI C compiler.
Lua also compiles unmodified as C++.
The instructions given below for building Lua are for Unix-like platforms,
such as Linux and Mac OS X.
such as Linux and macOS.
See also
<A HREF="#other">instructions for other systems</A>
and
@ -97,7 +99,7 @@ and
<P>
If you don't have the time or the inclination to compile Lua yourself,
get a binary from
<A HREF="http://lua-users.org/wiki/LuaBinaries">LuaBinaries</A>.
<A HREF="https://luabinaries.sourceforge.net">LuaBinaries</A>.
<H3>Building Lua</H3>
<P>
@ -107,7 +109,7 @@ Here are the details.
<OL>
<LI>
Open a terminal window and move to
the top-level directory, which is named <TT>lua-5.4.6</TT>.
the top-level directory, which is named <TT>lua-5.4.7</TT>.
The <TT>Makefile</TT> there controls both the build process and the installation process.
<P>
<LI>
@ -211,8 +213,8 @@ then try "<KBD>make linux-readline MYLIBS=-ltermcap</KBD>".
record the changes you've made.
<P>
On the other hand, if you need to customize some Lua features, you'll need
to edit <TT>src/luaconf.h</TT> before building and installing Lua.
On the other hand, if you need to customize some Lua features,
edit <TT>src/luaconf.h</TT> before building and installing Lua.
The edited file will be the one installed, and
it will be used by any Lua clients that you build, to ensure consistency.
Further customization is available to experts by editing the Lua sources.
@ -241,7 +243,7 @@ compiler:
</DL>
<P>
To use Lua as a library in your own programs, you'll need to know how to
To use Lua as a library in your own programs, you need to know how to
create and use libraries with your compiler. Moreover, to dynamically load
C libraries for Lua, you'll need to know how to create dynamic libraries
and you'll need to make sure that the Lua API functions are accessible to
@ -284,11 +286,11 @@ lists the
<H2><A NAME="license">License</A></H2>
<P>
<A HREF="http://www.opensource.org/docs/definition.php">
<IMG SRC="osi-certified-72x60.png" ALIGN="right" ALT="[osi certified]" STYLE="padding-left: 30px ;">
<A HREF="https://opensource.org/osd">
<IMG SRC="OSIApproved_100X125.png" ALIGN="right" ALT="[Open Source Initiative Approved License]" STYLE="padding-left: 1em" WIDTH=50>
</A>
Lua is free software distributed under the terms of the
<A HREF="http://www.opensource.org/licenses/mit-license.html">MIT license</A>
<A HREF="https://opensource.org/license/mit">MIT license</A>
reproduced below;
it may be used for any purpose, including commercial purposes,
at absolutely no cost without having to ask us.
@ -296,11 +298,11 @@ at absolutely no cost without having to ask us.
The only requirement is that if you do use Lua,
then you should give us credit by including the appropriate copyright notice somewhere in your product or its documentation.
For details, see
<A HREF="http://www.lua.org/license.html">this</A>.
For details, see the
<A HREF="https://www.lua.org/license.html">license page</A>.
<BLOCKQUOTE STYLE="padding-bottom: 0em">
Copyright &copy; 1994&ndash;2023 Lua.org, PUC-Rio.
Copyright &copy; 1994&ndash;2024 Lua.org, PUC-Rio.
<P>
Permission is hereby granted, free of charge, to any person obtaining a copy
@ -327,10 +329,10 @@ THE SOFTWARE.
<P CLASS="footer">
Last update:
Tue May 2 20:08:55 UTC 2023
Wed May 8 21:56:16 UTC 2024
</P>
<!--
Last change: revised for Lua 5.4.6
Last change: revised for Lua 5.4.7
-->
</BODY>

View File

@ -18,14 +18,14 @@
#define LUA_VERSION_MAJOR "5"
#define LUA_VERSION_MINOR "4"
#define LUA_VERSION_RELEASE "6"
#define LUA_VERSION_RELEASE "7"
#define LUA_VERSION_NUM 504
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 6)
#define LUA_VERSION_RELEASE_NUM (LUA_VERSION_NUM * 100 + 7)
#define LUA_VERSION "Lua " LUA_VERSION_MAJOR "." LUA_VERSION_MINOR
#define LUA_RELEASE LUA_VERSION "." LUA_VERSION_RELEASE
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2023 Lua.org, PUC-Rio"
#define LUA_COPYRIGHT LUA_RELEASE " Copyright (C) 1994-2024 Lua.org, PUC-Rio"
#define LUA_AUTHORS "R. Ierusalimschy, L. H. de Figueiredo, W. Celes"
@ -497,7 +497,7 @@ struct lua_Debug {
/******************************************************************************
* Copyright (C) 1994-2023 Lua.org, PUC-Rio.
* Copyright (C) 1994-2024 Lua.org, PUC-Rio.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the

View File

@ -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 suffix after the mark is the module version,
** as in "mod-v1.2.so".
*/
#define LUA_IGMARK "-"
/* }================================================================== */

View File

@ -417,9 +417,9 @@ LUA_API const char *lua_tolstring (lua_State *L, int idx, size_t *len) {
o = index2value(L, idx); /* previous call may reallocate the stack */
}
if (len != NULL)
*len = vslen(o);
*len = tsslen(tsvalue(o));
lua_unlock(L);
return svalue(o);
return getstr(tsvalue(o));
}

View File

@ -80,6 +80,7 @@ static int pushglobalfuncname (lua_State *L, lua_Debug *ar) {
int top = lua_gettop(L);
lua_getinfo(L, "f", ar); /* push function */
lua_getfield(L, LUA_REGISTRYINDEX, LUA_LOADED_TABLE);
luaL_checkstack(L, 6, "not enough stack"); /* slots for 'findfield' */
if (findfield(L, top + 1, 2)) {
const char *name = lua_tostring(L, -1);
if (strncmp(name, LUA_GNAME ".", 3) == 0) { /* name start with '_G.'? */
@ -249,11 +250,13 @@ LUALIB_API int luaL_fileresult (lua_State *L, int stat, const char *fname) {
return 1;
}
else {
const char *msg;
luaL_pushfail(L);
msg = (en != 0) ? strerror(en) : "(no extra info)";
if (fname)
lua_pushfstring(L, "%s: %s", fname, strerror(en));
lua_pushfstring(L, "%s: %s", fname, msg);
else
lua_pushstring(L, strerror(en));
lua_pushstring(L, msg);
lua_pushinteger(L, en);
return 3;
}
@ -732,9 +735,12 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
static int errfile (lua_State *L, const char *what, int fnameindex) {
const char *serr = strerror(errno);
int err = errno;
const char *filename = lua_tostring(L, fnameindex) + 1;
lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
if (err != 0)
lua_pushfstring(L, "cannot %s %s: %s", what, filename, strerror(err));
else
lua_pushfstring(L, "cannot %s %s", what, filename);
lua_remove(L, fnameindex);
return LUA_ERRFILE;
}
@ -787,6 +793,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
}
else {
lua_pushfstring(L, "@%s", filename);
errno = 0;
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
}
@ -796,6 +803,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
if (c == LUA_SIGNATURE[0]) { /* binary file? */
lf.n = 0; /* remove possible newline */
if (filename) { /* "real" file? */
errno = 0;
lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
skipcomment(lf.f, &c); /* re-read initial portion */
@ -803,6 +811,7 @@ LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
}
if (c != EOF)
lf.buff[lf.n++] = c; /* 'c' is the first character of the stream */
errno = 0;
status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
readstatus = ferror(lf.f);
if (filename) fclose(lf.f); /* close file (even in case of errors) */
@ -1025,9 +1034,14 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
}
/*
** Standard panic funcion just prints an error message. The test
** with 'lua_type' avoids possible memory errors in 'lua_tostring'.
*/
static int panic (lua_State *L) {
const char *msg = lua_tostring(L, -1);
if (msg == NULL) msg = "error object is not a string";
const char *msg = (lua_type(L, -1) == LUA_TSTRING)
? lua_tostring(L, -1)
: "error object is not a string";
lua_writestringerror("PANIC: unprotected error in call to Lua API (%s)\n",
msg);
return 0; /* return to Lua to abort */

View File

@ -415,7 +415,7 @@ int luaK_codeABx (FuncState *fs, OpCode o, int a, unsigned int bc) {
/*
** Format and emit an 'iAsBx' instruction.
*/
int luaK_codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
static int codeAsBx (FuncState *fs, OpCode o, int a, int bc) {
unsigned int b = bc + OFFSET_sBx;
lua_assert(getOpMode(o) == iAsBx);
lua_assert(a <= MAXARG_A && b <= MAXARG_Bx);
@ -671,7 +671,7 @@ static int fitsBx (lua_Integer i) {
void luaK_int (FuncState *fs, int reg, lua_Integer i) {
if (fitsBx(i))
luaK_codeAsBx(fs, OP_LOADI, reg, cast_int(i));
codeAsBx(fs, OP_LOADI, reg, cast_int(i));
else
luaK_codek(fs, reg, luaK_intK(fs, i));
}
@ -680,7 +680,7 @@ void luaK_int (FuncState *fs, int reg, lua_Integer i) {
static void luaK_float (FuncState *fs, int reg, lua_Number f) {
lua_Integer fi;
if (luaV_flttointeger(f, &fi, F2Ieq) && fitsBx(fi))
luaK_codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
codeAsBx(fs, OP_LOADF, reg, cast_int(fi));
else
luaK_codek(fs, reg, luaK_numberK(fs, f));
}
@ -776,7 +776,8 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) {
break;
}
case VLOCAL: { /* already in a register */
e->u.info = e->u.var.ridx;
int temp = e->u.var.ridx;
e->u.info = temp; /* (can't do a direct assignment; values overlap) */
e->k = VNONRELOC; /* becomes a non-relocatable value */
break;
}
@ -1025,7 +1026,7 @@ static int luaK_exp2K (FuncState *fs, expdesc *e) {
** in the range of R/K indices).
** Returns 1 iff expression is K.
*/
int luaK_exp2RK (FuncState *fs, expdesc *e) {
static int exp2RK (FuncState *fs, expdesc *e) {
if (luaK_exp2K(fs, e))
return 1;
else { /* not a constant in the right range: put it in a register */
@ -1037,7 +1038,7 @@ int luaK_exp2RK (FuncState *fs, expdesc *e) {
static void codeABRK (FuncState *fs, OpCode o, int a, int b,
expdesc *ec) {
int k = luaK_exp2RK(fs, ec);
int k = exp2RK(fs, ec);
luaK_codeABCk(fs, o, a, b, ec->u.info, k);
}
@ -1215,7 +1216,7 @@ static void codenot (FuncState *fs, expdesc *e) {
/*
** Check whether expression 'e' is a small literal string
** Check whether expression 'e' is a short literal string
*/
static int isKstr (FuncState *fs, expdesc *e) {
return (e->k == VK && !hasjumps(e) && e->u.info <= MAXARG_B &&
@ -1225,7 +1226,7 @@ static int isKstr (FuncState *fs, expdesc *e) {
/*
** Check whether expression 'e' is a literal integer.
*/
int luaK_isKint (expdesc *e) {
static int isKint (expdesc *e) {
return (e->k == VKINT && !hasjumps(e));
}
@ -1235,7 +1236,7 @@ int luaK_isKint (expdesc *e) {
** proper range to fit in register C
*/
static int isCint (expdesc *e) {
return luaK_isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C));
return isKint(e) && (l_castS2U(e->u.ival) <= l_castS2U(MAXARG_C));
}
@ -1244,7 +1245,7 @@ static int isCint (expdesc *e) {
** proper range to fit in register sC
*/
static int isSCint (expdesc *e) {
return luaK_isKint(e) && fitsC(e->u.ival);
return isKint(e) && fitsC(e->u.ival);
}
@ -1283,15 +1284,17 @@ void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k) {
if (t->k == VUPVAL && !isKstr(fs, k)) /* upvalue indexed by non 'Kstr'? */
luaK_exp2anyreg(fs, t); /* put it in a register */
if (t->k == VUPVAL) {
t->u.ind.t = t->u.info; /* upvalue index */
t->u.ind.idx = k->u.info; /* literal string */
int temp = t->u.info; /* upvalue index */
lua_assert(isKstr(fs, k));
t->u.ind.t = temp; /* (can't do a direct assignment; values overlap) */
t->u.ind.idx = k->u.info; /* literal short string */
t->k = VINDEXUP;
}
else {
/* register index of the table */
t->u.ind.t = (t->k == VLOCAL) ? t->u.var.ridx: t->u.info;
if (isKstr(fs, k)) {
t->u.ind.idx = k->u.info; /* literal string */
t->u.ind.idx = k->u.info; /* literal short string */
t->k = VINDEXSTR;
}
else if (isCint(k)) {
@ -1459,7 +1462,7 @@ static void codebinK (FuncState *fs, BinOpr opr,
*/
static int finishbinexpneg (FuncState *fs, expdesc *e1, expdesc *e2,
OpCode op, int line, TMS event) {
if (!luaK_isKint(e2))
if (!isKint(e2))
return 0; /* not an integer constant */
else {
lua_Integer i2 = e2->u.ival;
@ -1592,7 +1595,7 @@ static void codeeq (FuncState *fs, BinOpr opr, expdesc *e1, expdesc *e2) {
op = OP_EQI;
r2 = im; /* immediate operand */
}
else if (luaK_exp2RK(fs, e2)) { /* 2nd expression is constant? */
else if (exp2RK(fs, e2)) { /* 2nd expression is constant? */
op = OP_EQK;
r2 = e2->u.info; /* constant index */
}
@ -1658,7 +1661,7 @@ void luaK_infix (FuncState *fs, BinOpr op, expdesc *v) {
}
case OPR_EQ: case OPR_NE: {
if (!tonumeral(v, NULL))
luaK_exp2RK(fs, v);
exp2RK(fs, v);
/* else keep numeral, which may be an immediate operand */
break;
}

View File

@ -61,10 +61,8 @@ typedef enum UnOpr { OPR_MINUS, OPR_BNOT, OPR_NOT, OPR_LEN, OPR_NOUNOPR } UnOpr;
LUAI_FUNC int luaK_code (FuncState *fs, Instruction i);
LUAI_FUNC int luaK_codeABx (FuncState *fs, OpCode o, int A, unsigned int Bx);
LUAI_FUNC int luaK_codeAsBx (FuncState *fs, OpCode o, int A, int Bx);
LUAI_FUNC int luaK_codeABCk (FuncState *fs, OpCode o, int A,
int B, int C, int k);
LUAI_FUNC int luaK_isKint (expdesc *e);
LUAI_FUNC int luaK_exp2const (FuncState *fs, const expdesc *e, TValue *v);
LUAI_FUNC void luaK_fixline (FuncState *fs, int line);
LUAI_FUNC void luaK_nil (FuncState *fs, int from, int n);
@ -76,7 +74,6 @@ LUAI_FUNC int luaK_exp2anyreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2anyregup (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2nextreg (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_exp2val (FuncState *fs, expdesc *e);
LUAI_FUNC int luaK_exp2RK (FuncState *fs, expdesc *e);
LUAI_FUNC void luaK_self (FuncState *fs, expdesc *e, expdesc *key);
LUAI_FUNC void luaK_indexed (FuncState *fs, expdesc *t, expdesc *k);
LUAI_FUNC void luaK_goiftrue (FuncState *fs, expdesc *e);

View File

@ -31,7 +31,7 @@
#define noLuaClosure(f) ((f) == NULL || (f)->c.tt == LUA_VCCL)
#define LuaClosure(f) ((f) != NULL && (f)->c.tt == LUA_VLCL)
static const char *funcnamefromcall (lua_State *L, CallInfo *ci,
@ -254,7 +254,7 @@ LUA_API const char *lua_setlocal (lua_State *L, const lua_Debug *ar, int n) {
static void funcinfo (lua_Debug *ar, Closure *cl) {
if (noLuaClosure(cl)) {
if (!LuaClosure(cl)) {
ar->source = "=[C]";
ar->srclen = LL("=[C]");
ar->linedefined = -1;
@ -288,18 +288,19 @@ static int nextline (const Proto *p, int currentline, int pc) {
static void collectvalidlines (lua_State *L, Closure *f) {
if (noLuaClosure(f)) {
if (!LuaClosure(f)) {
setnilvalue(s2v(L->top.p));
api_incr_top(L);
}
else {
int i;
TValue v;
const Proto *p = f->l.p;
int currentline = p->linedefined;
Table *t = luaH_new(L); /* new table to store active lines */
sethvalue2s(L, L->top.p, t); /* push it on stack */
api_incr_top(L);
if (p->lineinfo != NULL) { /* proto with debug information? */
int i;
TValue v;
setbtvalue(&v); /* boolean 'true' to be the value of all indices */
if (!p->is_vararg) /* regular function? */
i = 0; /* consider all instructions */
@ -314,6 +315,7 @@ static void collectvalidlines (lua_State *L, Closure *f) {
}
}
}
}
static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) {
@ -339,7 +341,7 @@ static int auxgetinfo (lua_State *L, const char *what, lua_Debug *ar,
}
case 'u': {
ar->nups = (f == NULL) ? 0 : f->c.nupvalues;
if (noLuaClosure(f)) {
if (!LuaClosure(f)) {
ar->isvararg = 1;
ar->nparams = 0;
}
@ -417,40 +419,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)) ? svalue(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 +477,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,
static const char *basicgetobjname (const Proto *p, int *ppc, int reg,
const char **name) {
int pc;
*name = luaF_getlocalname(p, reg + 1, lastpc);
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 +507,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 +589,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 = svalue(&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 */
@ -627,7 +644,7 @@ static const char *funcnamefromcode (lua_State *L, const Proto *p,
default:
return NULL; /* cannot find a reasonable name */
}
*name = getstr(G(L)->tmname[tm]) + 2;
*name = getshrstr(G(L)->tmname[tm]) + 2;
return "metamethod";
}
@ -865,6 +882,28 @@ static int changedline (const Proto *p, int oldpc, int newpc) {
}
/*
** Traces Lua calls. If code is running the first instruction of a function,
** and function is not vararg, and it is not coming from an yield,
** calls 'luaD_hookcall'. (Vararg functions will call 'luaD_hookcall'
** after adjusting its variable arguments; otherwise, they could call
** a line/count hook before the call hook. Functions coming from
** an yield already called 'luaD_hookcall' before yielding.)
*/
int luaG_tracecall (lua_State *L) {
CallInfo *ci = L->ci;
Proto *p = ci_func(ci)->p;
ci->u.l.trap = 1; /* ensure hooks will be checked */
if (ci->u.l.savedpc == p->code) { /* first instruction (not resuming)? */
if (p->is_vararg)
return 0; /* hooks will start at VARARGPREP instruction */
else if (!(ci->callstatus & CIST_HOOKYIELD)) /* not yieded? */
luaD_hookcall(L, ci); /* check 'call' hook */
}
return 1; /* keep 'trap' on */
}
/*
** Traces the execution of a Lua function. Called before the execution
** of each opcode, when debug is on. 'L->oldpc' stores the last
@ -888,12 +927,12 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
}
pc++; /* reference is always next instruction */
ci->u.l.savedpc = pc; /* save 'pc' */
counthook = (--L->hookcount == 0 && (mask & LUA_MASKCOUNT));
counthook = (mask & LUA_MASKCOUNT) && (--L->hookcount == 0);
if (counthook)
resethookcount(L); /* reset count */
else if (!(mask & LUA_MASKLINE))
return 1; /* no line hook and count != 0; nothing to be done now */
if (ci->callstatus & CIST_HOOKYIELD) { /* called hook last time? */
if (ci->callstatus & CIST_HOOKYIELD) { /* hook yielded last time? */
ci->callstatus &= ~CIST_HOOKYIELD; /* erase mark */
return 1; /* do not call hook again (VM yielded, so it did not move) */
}
@ -915,7 +954,6 @@ int luaG_traceexec (lua_State *L, const Instruction *pc) {
if (L->status == LUA_YIELD) { /* did hook yield? */
if (counthook)
L->hookcount = 1; /* undo decrement to zero */
ci->u.l.savedpc--; /* undo increment (resume will increment it again) */
ci->callstatus |= CIST_HOOKYIELD; /* mark that it yielded */
luaD_throw(L, LUA_YIELD);
}

View File

@ -58,6 +58,7 @@ LUAI_FUNC const char *luaG_addinfo (lua_State *L, const char *msg,
TString *src, int line);
LUAI_FUNC l_noret luaG_errormsg (lua_State *L);
LUAI_FUNC int luaG_traceexec (lua_State *L, const Instruction *pc);
LUAI_FUNC int luaG_tracecall (lua_State *L);
#endif

View File

@ -409,7 +409,7 @@ static void rethook (lua_State *L, CallInfo *ci, int nres) {
** stack, below original 'func', so that 'luaD_precall' can call it. Raise
** an error if there is no '__call' metafield.
*/
StkId luaD_tryfuncTM (lua_State *L, StkId func) {
static StkId tryfuncTM (lua_State *L, StkId func) {
const TValue *tm;
StkId p;
checkstackGCp(L, 1, func); /* space for metamethod */
@ -568,7 +568,7 @@ int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
return -1;
}
default: { /* not a function */
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
func = tryfuncTM(L, func); /* try to get '__call' metamethod */
/* return luaD_pretailcall(L, ci, func, narg1 + 1, delta); */
narg1++;
goto retry; /* try again */
@ -609,7 +609,7 @@ CallInfo *luaD_precall (lua_State *L, StkId func, int nresults) {
return ci;
}
default: { /* not a function */
func = luaD_tryfuncTM(L, func); /* try to get '__call' metamethod */
func = tryfuncTM(L, func); /* try to get '__call' metamethod */
/* return luaD_precall(L, func, nresults); */
goto retry; /* try again with metamethod */
}
@ -792,6 +792,10 @@ static void resume (lua_State *L, void *ud) {
lua_assert(L->status == LUA_YIELD);
L->status = LUA_OK; /* mark that it is running (again) */
if (isLua(ci)) { /* yielded inside a hook? */
/* undo increment made by 'luaG_traceexec': instruction was not
executed yet */
lua_assert(ci->callstatus & CIST_HOOKYIELD);
ci->u.l.savedpc--;
L->top.p = firstArg; /* discard arguments */
luaV_execute(L, ci); /* just continue running Lua code */
}

View File

@ -71,7 +71,6 @@ LUAI_FUNC int luaD_pretailcall (lua_State *L, CallInfo *ci, StkId func,
LUAI_FUNC CallInfo *luaD_precall (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_call (lua_State *L, StkId func, int nResults);
LUAI_FUNC void luaD_callnoyield (lua_State *L, StkId func, int nResults);
LUAI_FUNC StkId luaD_tryfuncTM (lua_State *L, StkId func);
LUAI_FUNC int luaD_closeprotected (lua_State *L, ptrdiff_t level, int status);
LUAI_FUNC int luaD_pcall (lua_State *L, Pfunc func, void *u,
ptrdiff_t oldtop, ptrdiff_t ef);

View File

@ -542,10 +542,12 @@ static void traversestrongtable (global_State *g, Table *h) {
static lu_mem traversetable (global_State *g, Table *h) {
const char *weakkey, *weakvalue;
const TValue *mode = gfasttm(g, h->metatable, TM_MODE);
TString *smode;
markobjectN(g, h->metatable);
if (mode && ttisstring(mode) && /* is there a weak mode? */
(cast_void(weakkey = strchr(svalue(mode), 'k')),
cast_void(weakvalue = strchr(svalue(mode), 'v')),
if (mode && ttisshrstring(mode) && /* is there a weak mode? */
(cast_void(smode = tsvalue(mode)),
cast_void(weakkey = strchr(getshrstr(smode), 'k')),
cast_void(weakvalue = strchr(getshrstr(smode), 'v')),
(weakkey || weakvalue))) { /* is really weak? */
if (!weakkey) /* strong keys? */
traverseweakvalue(g, h);
@ -638,7 +640,9 @@ static int traversethread (global_State *g, lua_State *th) {
for (uv = th->openupval; uv != NULL; uv = uv->u.open.next)
markobject(g, uv); /* open upvalues cannot be collected */
if (g->gcstate == GCSatomic) { /* final traversal? */
for (; o < th->stack_last.p + EXTRA_STACK; o++)
if (!g->gcemergency)
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
for (o = th->top.p; o < th->stack_last.p + EXTRA_STACK; o++)
setnilvalue(s2v(o)); /* clear dead stack slice */
/* 'remarkupvals' may have removed thread from 'twups' list */
if (!isintwups(th) && th->openupval != NULL) {
@ -646,8 +650,6 @@ static int traversethread (global_State *g, lua_State *th) {
g->twups = th;
}
}
else if (!g->gcemergency)
luaD_shrinkstack(th); /* do not change stack in emergency cycle */
return 1 + stacksize(th);
}
@ -1409,7 +1411,7 @@ static void stepgenfull (lua_State *L, global_State *g) {
setminordebt(g);
}
else { /* another bad collection; stay in incremental mode */
g->GCestimate = gettotalbytes(g); /* first estimate */;
g->GCestimate = gettotalbytes(g); /* first estimate */
entersweep(L);
luaC_runtilstate(L, bitmask(GCSpause)); /* finish collection */
setpause(g);
@ -1604,7 +1606,7 @@ static lu_mem singlestep (lua_State *L) {
case GCSenteratomic: {
work = atomic(L); /* work is what was traversed by 'atomic' */
entersweep(L);
g->GCestimate = gettotalbytes(g); /* first estimate */;
g->GCestimate = gettotalbytes(g); /* first estimate */
break;
}
case GCSswpallgc: { /* sweep "regular" objects */
@ -1710,6 +1712,8 @@ static void fullinc (lua_State *L, global_State *g) {
entersweep(L); /* sweep everything to turn them back to white */
/* finish any pending sweep phase to start a new cycle */
luaC_runtilstate(L, bitmask(GCSpause));
luaC_runtilstate(L, bitmask(GCSpropagate)); /* start new cycle */
g->gcstate = GCSenteratomic; /* go straight to atomic phase */
luaC_runtilstate(L, bitmask(GCScallfin)); /* run up to finalizers */
/* estimate must be correct after a full GC cycle */
lua_assert(g->GCestimate == gettotalbytes(g));

View File

@ -245,8 +245,8 @@ static int f_gc (lua_State *L) {
*/
static int io_fclose (lua_State *L) {
LStream *p = tolstream(L);
int res = fclose(p->f);
return luaL_fileresult(L, (res == 0), NULL);
errno = 0;
return luaL_fileresult(L, (fclose(p->f) == 0), NULL);
}
@ -272,6 +272,7 @@ static int io_open (lua_State *L) {
LStream *p = newfile(L);
const char *md = mode; /* to traverse/check mode */
luaL_argcheck(L, l_checkmode(md), 2, "invalid mode");
errno = 0;
p->f = fopen(filename, mode);
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
}
@ -292,6 +293,7 @@ static int io_popen (lua_State *L) {
const char *mode = luaL_optstring(L, 2, "r");
LStream *p = newprefile(L);
luaL_argcheck(L, l_checkmodep(mode), 2, "invalid mode");
errno = 0;
p->f = l_popen(L, filename, mode);
p->closef = &io_pclose;
return (p->f == NULL) ? luaL_fileresult(L, 0, filename) : 1;
@ -300,6 +302,7 @@ static int io_popen (lua_State *L) {
static int io_tmpfile (lua_State *L) {
LStream *p = newfile(L);
errno = 0;
p->f = tmpfile();
return (p->f == NULL) ? luaL_fileresult(L, 0, NULL) : 1;
}
@ -567,6 +570,7 @@ static int g_read (lua_State *L, FILE *f, int first) {
int nargs = lua_gettop(L) - 1;
int n, success;
clearerr(f);
errno = 0;
if (nargs == 0) { /* no arguments? */
success = read_line(L, f, 1);
n = first + 1; /* to return 1 result */
@ -660,6 +664,7 @@ static int io_readline (lua_State *L) {
static int g_write (lua_State *L, FILE *f, int arg) {
int nargs = lua_gettop(L) - arg;
int status = 1;
errno = 0;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
/* optimization: could be done exactly as for strings */
@ -678,7 +683,8 @@ static int g_write (lua_State *L, FILE *f, int arg) {
}
if (l_likely(status))
return 1; /* file handle already on stack top */
else return luaL_fileresult(L, status, NULL);
else
return luaL_fileresult(L, status, NULL);
}
@ -703,6 +709,7 @@ static int f_seek (lua_State *L) {
l_seeknum offset = (l_seeknum)p3;
luaL_argcheck(L, (lua_Integer)offset == p3, 3,
"not an integer in proper range");
errno = 0;
op = l_fseek(f, offset, mode[op]);
if (l_unlikely(op))
return luaL_fileresult(L, 0, NULL); /* error */
@ -719,19 +726,25 @@ static int f_setvbuf (lua_State *L) {
FILE *f = tofile(L);
int op = luaL_checkoption(L, 2, NULL, modenames);
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], (size_t)sz);
int res;
errno = 0;
res = setvbuf(f, NULL, mode[op], (size_t)sz);
return luaL_fileresult(L, res == 0, NULL);
}
static int io_flush (lua_State *L) {
return luaL_fileresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
FILE *f = getiofile(L, IO_OUTPUT);
errno = 0;
return luaL_fileresult(L, fflush(f) == 0, NULL);
}
static int f_flush (lua_State *L) {
return luaL_fileresult(L, fflush(tofile(L)) == 0, NULL);
FILE *f = tofile(L);
errno = 0;
return luaL_fileresult(L, fflush(f) == 0, NULL);
}

View File

@ -249,6 +249,15 @@ static int math_type (lua_State *L) {
** ===================================================================
*/
/*
** This code uses lots of shifts. ANSI C does not allow shifts greater
** than or equal to the width of the type being shifted, so some shifts
** are written in convoluted ways to match that restriction. For
** preprocessor tests, it assumes a width of 32 bits, so the maximum
** shift there is 31 bits.
*/
/* number of binary digits in the mantissa of a float */
#define FIGS l_floatatt(MANT_DIG)
@ -271,16 +280,19 @@ static int math_type (lua_State *L) {
/* 'long' has at least 64 bits */
#define Rand64 unsigned long
#define SRand64 long
#elif !defined(LUA_USE_C89) && defined(LLONG_MAX)
/* there is a 'long long' type (which must have at least 64 bits) */
#define Rand64 unsigned long long
#define SRand64 long long
#elif ((LUA_MAXUNSIGNED >> 31) >> 31) >= 3
/* 'lua_Unsigned' has at least 64 bits */
#define Rand64 lua_Unsigned
#define SRand64 lua_Integer
#endif
@ -319,23 +331,30 @@ static Rand64 nextrand (Rand64 *state) {
}
/* must take care to not shift stuff by more than 63 slots */
/*
** Convert bits from a random integer into a float in the
** interval [0,1), getting the higher FIG bits from the
** random unsigned integer and converting that to a float.
** Some old Microsoft compilers cannot cast an unsigned long
** to a floating-point number, so we use a signed long as an
** intermediary. When lua_Number is float or double, the shift ensures
** that 'sx' is non negative; in that case, a good compiler will remove
** the correction.
*/
/* must throw out the extra (64 - FIGS) bits */
#define shift64_FIG (64 - FIGS)
/* to scale to [0, 1), multiply by scaleFIG = 2^(-FIGS) */
/* 2^(-FIGS) == 2^-1 / 2^(FIGS-1) */
#define scaleFIG (l_mathop(0.5) / ((Rand64)1 << (FIGS - 1)))
static lua_Number I2d (Rand64 x) {
return (lua_Number)(trim64(x) >> shift64_FIG) * scaleFIG;
SRand64 sx = (SRand64)(trim64(x) >> shift64_FIG);
lua_Number res = (lua_Number)(sx) * scaleFIG;
if (sx < 0)
res += l_mathop(1.0); /* correct the two's complement if negative */
lua_assert(0 <= res && res < 1);
return res;
}
/* convert a 'Rand64' to a 'lua_Unsigned' */
@ -471,8 +490,6 @@ static lua_Number I2d (Rand64 x) {
#else /* 32 < FIGS <= 64 */
/* must take care to not shift stuff by more than 31 slots */
/* 2^(-FIGS) = 1.0 / 2^30 / 2^3 / 2^(FIGS-33) */
#define scaleFIG \
(l_mathop(1.0) / (UONE << 30) / l_mathop(8.0) / (UONE << (FIGS - 33)))

View File

@ -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.

View File

@ -542,7 +542,7 @@ const char *luaO_pushvfstring (lua_State *L, const char *fmt, va_list argp) {
addstr2buff(&buff, fmt, strlen(fmt)); /* rest of 'fmt' */
clearbuff(&buff); /* empty buffer into the stack */
lua_assert(buff.pushed == 1);
return svalue(s2v(L->top.p - 1));
return getstr(tsvalue(s2v(L->top.p - 1)));
}

View File

@ -386,7 +386,7 @@ typedef struct GCObject {
typedef struct TString {
CommonHeader;
lu_byte extra; /* reserved words for short strings; "has hash" for longs */
lu_byte shrlen; /* length for short strings */
lu_byte shrlen; /* length for short strings, 0xFF for long strings */
unsigned int hash;
union {
size_t lnglen; /* length for long strings */
@ -398,19 +398,17 @@ typedef struct TString {
/*
** Get the actual string (array of bytes) from a 'TString'.
** Get the actual string (array of bytes) from a 'TString'. (Generic
** version and specialized versions for long and short strings.)
*/
#define getstr(ts) ((ts)->contents)
#define getlngstr(ts) check_exp((ts)->shrlen == 0xFF, (ts)->contents)
#define getshrstr(ts) check_exp((ts)->shrlen != 0xFF, (ts)->contents)
/* get the actual string (array of bytes) from a Lua value */
#define svalue(o) getstr(tsvalue(o))
/* get string length from 'TString *s' */
#define tsslen(s) ((s)->tt == LUA_VSHRSTR ? (s)->shrlen : (s)->u.lnglen)
/* get string length from 'TValue *o' */
#define vslen(o) tsslen(tsvalue(o))
#define tsslen(s) \
((s)->shrlen != 0xFF ? (s)->shrlen : (s)->u.lnglen)
/* }================================================================== */

View File

@ -210,15 +210,15 @@ OP_LOADNIL,/* A B R[A], R[A+1], ..., R[A+B] := nil */
OP_GETUPVAL,/* A B R[A] := UpValue[B] */
OP_SETUPVAL,/* A B UpValue[B] := R[A] */
OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:string] */
OP_GETTABUP,/* A B C R[A] := UpValue[B][K[C]:shortstring] */
OP_GETTABLE,/* A B C R[A] := R[B][R[C]] */
OP_GETI,/* A B C R[A] := R[B][C] */
OP_GETFIELD,/* A B C R[A] := R[B][K[C]:string] */
OP_GETFIELD,/* A B C R[A] := R[B][K[C]:shortstring] */
OP_SETTABUP,/* A B C UpValue[A][K[B]:string] := RK(C) */
OP_SETTABUP,/* A B C UpValue[A][K[B]:shortstring] := RK(C) */
OP_SETTABLE,/* A B C R[A][R[B]] := RK(C) */
OP_SETI,/* A B C R[A][B] := RK(C) */
OP_SETFIELD,/* A B C R[A][K[B]:string] := RK(C) */
OP_SETFIELD,/* A B C R[A][K[B]:shortstring] := RK(C) */
OP_NEWTABLE,/* A B C k R[A] := {} */

View File

@ -155,6 +155,7 @@ static int os_execute (lua_State *L) {
static int os_remove (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
errno = 0;
return luaL_fileresult(L, remove(filename) == 0, filename);
}
@ -162,6 +163,7 @@ static int os_remove (lua_State *L) {
static int os_rename (lua_State *L) {
const char *fromname = luaL_checkstring(L, 1);
const char *toname = luaL_checkstring(L, 2);
errno = 0;
return luaL_fileresult(L, rename(fromname, toname) == 0, NULL);
}

View File

@ -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;

Some files were not shown because too many files have changed in this diff Show More