Skip to content

Commit dba57cf

Browse files
committed
Merge remote-tracking branch 'upstream/v2.1' into v2.1
2 parents 631f864 + 0d313b2 commit dba57cf

27 files changed

+391
-167
lines changed

doc/extensions.html

+40-13
Original file line numberDiff line numberDiff line change
@@ -160,13 +160,33 @@ <h3 id="xpcall"><tt>xpcall(f, err [,args...])</tt> passes arguments</h3>
160160
which is called in a protected context.
161161
</p>
162162

163-
<h3 id="load"><tt>loadfile()</tt> etc. handle UTF-8 source code</h3>
163+
<h3 id="load"><tt>load*()</tt> handle UTF-8 source code</h3>
164164
<p>
165165
Non-ASCII characters are handled transparently by the Lua source code parser.
166166
This allows the use of UTF-8 characters in identifiers and strings.
167167
A UTF-8 BOM is skipped at the start of the source code.
168168
</p>
169169

170+
<h3 id="load_mode"><tt>load*()</tt> add a mode parameter</h3>
171+
<p>
172+
As an extension from Lua 5.2, the functions <tt>loadstring()</tt>,
173+
<tt>loadfile()</tt> and (new) <tt>load()</tt> add an optional
174+
<tt>mode</tt> parameter.
175+
</p>
176+
<p>
177+
The default mode string is <tt>"bt"</tt>, which allows loading of both
178+
source code and bytecode. Use <tt>"t"</tt> to allow only source code
179+
or <tt>"b"</tt> to allow only bytecode to be loaded.
180+
</p>
181+
<p>
182+
By default, the <tt>load*</tt> functions generate the native bytecode format.
183+
For cross-compilation purposes, add <tt>W</tt> to the mode string to
184+
force the 32 bit format and <tt>X</tt> to force the 64 bit format.
185+
Add both to force the opposite format. Note that non-native bytecode
186+
generated by <tt>load*</tt> cannot be run, but can still be passed
187+
to <tt>string.dump</tt>.
188+
</p>
189+
170190
<h3 id="tostring"><tt>tostring()</tt> etc. canonicalize NaN and &plusmn;Inf</h3>
171191
<p>
172192
All number-to-string conversions consistently convert non-finite numbers
@@ -186,26 +206,33 @@ <h3 id="tonumber"><tt>tonumber()</tt> etc. use builtin string to number conversi
186206
numbers (e.g. <tt>0x1.5p-3</tt>).
187207
</p>
188208

189-
<h3 id="string_dump"><tt>string.dump(f [,strip])</tt> generates portable bytecode</h3>
209+
<h3 id="string_dump"><tt>string.dump(f [,mode])</tt> generates portable bytecode</h3>
190210
<p>
191211
An extra argument has been added to <tt>string.dump()</tt>. If set to
192-
<tt>true</tt>, 'stripped' bytecode without debug information is
193-
generated. This speeds up later bytecode loading and reduces memory
194-
usage. See also the
212+
<tt>true</tt> or to a string which contains the character <tt>s</tt>,
213+
'stripped' bytecode without debug information is generated. This speeds
214+
up later bytecode loading and reduces memory usage. See also the
195215
<a href="running.html#opt_b"><tt>-b</tt> command line option</a>.
196216
</p>
197217
<p>
198218
The generated bytecode is portable and can be loaded on any architecture
199-
that LuaJIT supports, independent of word size or endianess. However, the
200-
bytecode compatibility versions must match. Bytecode stays compatible
201-
for dot releases (x.y.0 &rarr; x.y.1), but may change with major or
202-
minor releases (2.0 &rarr; 2.1) or between any beta release. Foreign
203-
bytecode (e.g. from Lua 5.1) is incompatible and cannot be loaded.
219+
that LuaJIT supports. However, the bytecode compatibility versions must
220+
match. Bytecode only stays compatible within a major+minor version
221+
(x.y.aaa &rarr; x.y.bbb), except for development branches. Foreign bytecode
222+
(e.g. from Lua 5.1) is incompatible and cannot be loaded.
204223
</p>
205224
<p>
206225
Note: <tt>LJ_GC64</tt> mode requires a different frame layout, which implies
207-
a different, incompatible bytecode format for all 64 bit ports. This may be
208-
rectified in the future.
226+
a different, incompatible bytecode format between 32 bit and 64 bit ports.
227+
This may be rectified in the future. In the meantime, use the <tt>W</tt>
228+
and </tt>X</tt> <a href="#load_mode">modes of the <tt>load*</tt> functions</a>
229+
for cross-compilation purposes.
230+
</p>
231+
<p>
232+
Due to VM hardening, bytecode is not deterministic. Add <tt>d</tt> to the
233+
mode string to dump it in a deterministic manner: identical source code
234+
always gives a byte-for-byte identical bytecode dump. This feature is
235+
mainly useful for reproducible builds.
209236
</p>
210237

211238
<h3 id="table_new"><tt>table.new(narray, nhash)</tt> allocates a pre-sized table</h3>
@@ -286,7 +313,7 @@ <h2 id="lua52">Extensions from Lua 5.2</h2>
286313
</p>
287314
<ul>
288315
<li><tt>goto</tt> and <tt>::labels::</tt>.</li>
289-
<li>Hex escapes <tt>'\x3F'</tt> and <tt>'\*'</tt> escape in strings.</li>
316+
<li>Hex escapes <tt>'\x3F'</tt> and <tt>'\z'</tt> escape in strings.</li>
290317
<li><tt>load(string|reader [, chunkname [,mode [,env]]])</tt>.</li>
291318
<li><tt>loadstring()</tt> is an alias for <tt>load()</tt>.</li>
292319
<li><tt>loadfile(filename [,mode [,env]])</tt>.</li>

doc/running.html

+3
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,9 @@ <h3 id="opt_b"><tt>-b[options] input output</tt></h3>
106106
<li><tt>-l</tt> &mdash; Only list bytecode.</li>
107107
<li><tt>-s</tt> &mdash; Strip debug info (this is the default).</li>
108108
<li><tt>-g</tt> &mdash; Keep debug info.</li>
109+
<li><tt>-W</tt> &mdash; Generate 32 bit (non-GC64) bytecode.</li>
110+
<li><tt>-X</tt> &mdash; Generate 64 bit (GC64) bytecode.</li>
111+
<li><tt>-d</tt> &mdash; Generate bytecode in deterministic manner.</li>
109112
<li><tt>-n name</tt> &mdash; Set module name (default: auto-detect from input name)</li>
110113
<li><tt>-t type</tt> &mdash; Set output file type (default: auto-detect from output name).</li>
111114
<li><tt>-a arch</tt> &mdash; Override architecture for object files (default: native).</li>

dynasm/dasm_x86.lua

+2
Original file line numberDiff line numberDiff line change
@@ -1151,6 +1151,8 @@ local map_op = {
11511151
rep_0 = "F3",
11521152
repe_0 = "F3",
11531153
repz_0 = "F3",
1154+
endbr32_0 = "F30F1EFB",
1155+
endbr64_0 = "F30F1EFA",
11541156
-- F4: *hlt
11551157
cmc_0 = "F5",
11561158
-- F6: test... mb,i; div... mb

dynasm/dynasm.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ local function wline(line, needindent)
7575
g_synclineno = g_synclineno + 1
7676
end
7777

78-
-- Write assembler line as a comment, if requestd.
78+
-- Write assembler line as a comment, if requested.
7979
local function wcomment(aline)
8080
if g_opt.comment then
8181
wline(g_opt.comment..aline..g_opt.endcomment, true)

src/host/genlibbc.lua

+50-41
Original file line numberDiff line numberDiff line change
@@ -138,65 +138,73 @@ local function fixup_dump(dump, fixup)
138138
return { dump = ndump, startbc = startbc, sizebc = sizebc }
139139
end
140140

141-
local function find_defs(src)
141+
local function find_defs(src, mode)
142142
local defs = {}
143143
for name, code in string.gmatch(src, "LJLIB_LUA%(([^)]*)%)%s*/%*(.-)%*/") do
144-
local env = {}
145144
local tcode, fixup = transform_lua(code)
146-
local func = assert(load(tcode, "", nil, env))()
147-
defs[name] = fixup_dump(string.dump(func, true), fixup)
145+
local func = assert(load(tcode, "", mode))
146+
defs[name] = fixup_dump(string.dump(func, mode), fixup)
148147
defs[#defs+1] = name
149148
end
150149
return defs
151150
end
152151

153-
local function gen_header(defs)
152+
local function gen_header(defs32, defs64)
154153
local t = {}
155154
local function w(x) t[#t+1] = x end
156155
w("/* This is a generated file. DO NOT EDIT! */\n\n")
157156
w("static const int libbc_endian = ") w(isbe and 1 or 0) w(";\n\n")
158-
local s, sb = "", ""
159-
for i,name in ipairs(defs) do
160-
local d = defs[name]
161-
s = s .. d.dump
162-
sb = sb .. string.char(i) .. ("\0"):rep(d.startbc - 1)
163-
.. (isbe and "\0\0\0\255" or "\255\0\0\0"):rep(d.sizebc)
164-
.. ("\0"):rep(#d.dump - d.startbc - d.sizebc*4)
165-
end
166-
w("static const uint8_t libbc_code[] = {\n")
167-
local n = 0
168-
for i=1,#s do
169-
local x = string.byte(s, i)
170-
local xb = string.byte(sb, i)
171-
if xb == 255 then
172-
local name = BCN[x]
173-
local m = #name + 4
174-
if n + m > 78 then n = 0; w("\n") end
175-
n = n + m
176-
w("BC_"); w(name)
157+
for j,defs in ipairs{defs64, defs32} do
158+
local s, sb = "", ""
159+
for i,name in ipairs(defs) do
160+
local d = defs[name]
161+
s = s .. d.dump
162+
sb = sb .. string.char(i) .. ("\0"):rep(d.startbc - 1)
163+
.. (isbe and "\0\0\0\255" or "\255\0\0\0"):rep(d.sizebc)
164+
.. ("\0"):rep(#d.dump - d.startbc - d.sizebc*4)
165+
end
166+
if j == 1 then
167+
w("static const uint8_t libbc_code[] = {\n#if LJ_FR2\n")
177168
else
178-
local m = x < 10 and 2 or (x < 100 and 3 or 4)
179-
if xb == 0 then
169+
w("\n#else\n")
170+
end
171+
local n = 0
172+
for i=1,#s do
173+
local x = string.byte(s, i)
174+
local xb = string.byte(sb, i)
175+
if xb == 255 then
176+
local name = BCN[x]
177+
local m = #name + 4
180178
if n + m > 78 then n = 0; w("\n") end
179+
n = n + m
180+
w("BC_"); w(name)
181181
else
182-
local name = defs[xb]:gsub("_", ".")
183-
if n ~= 0 then w("\n") end
184-
w("/* "); w(name); w(" */ ")
185-
n = #name + 7
182+
local m = x < 10 and 2 or (x < 100 and 3 or 4)
183+
if xb == 0 then
184+
if n + m > 78 then n = 0; w("\n") end
185+
else
186+
local name = defs[xb]:gsub("_", ".")
187+
if n ~= 0 then w("\n") end
188+
w("/* "); w(name); w(" */ ")
189+
n = #name + 7
190+
end
191+
n = n + m
192+
w(x)
186193
end
187-
n = n + m
188-
w(x)
194+
w(",")
189195
end
190-
w(",")
191196
end
192-
w("\n0\n};\n\n")
197+
w("\n#endif\n0\n};\n\n")
193198
w("static const struct { const char *name; int ofs; } libbc_map[] = {\n")
194-
local m = 0
195-
for _,name in ipairs(defs) do
196-
w('{"'); w(name); w('",'); w(m) w('},\n')
197-
m = m + #defs[name].dump
199+
local m32, m64 = 0, 0
200+
for i,name in ipairs(defs32) do
201+
assert(name == defs64[i])
202+
w('{"'); w(name); w('",'); w(m32) w('},\n')
203+
m32 = m32 + #defs32[name].dump
204+
m64 = m64 + #defs64[name].dump
205+
assert(m32 == m64)
198206
end
199-
w("{NULL,"); w(m); w("}\n};\n\n")
207+
w("{NULL,"); w(m32); w("}\n};\n\n")
200208
return table.concat(t)
201209
end
202210

@@ -219,7 +227,8 @@ end
219227

220228
local outfile = parse_arg(arg)
221229
local src = read_files(arg)
222-
local defs = find_defs(src)
223-
local hdr = gen_header(defs)
230+
local defs32 = find_defs(src, "Wdts")
231+
local defs64 = find_defs(src, "Xdts")
232+
local hdr = gen_header(defs32, defs64)
224233
write_file(outfile, hdr)
225234

src/host/genversion.lua

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ local function file_write_mod(file, data)
2929
assert(fp:close())
3030
end
3131

32-
local text = file_read(FILE_ROLLING_H)
32+
local text = file_read(FILE_ROLLING_H):gsub("#error.-\n", "")
3333
local relver = file_read(FILE_RELVER_TXT):match("(%d+)")
3434

3535
if relver then

src/jit/bcsave.lua

+21-10
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ Save LuaJIT bytecode: luajit -b[options] input output
2929
-l Only list bytecode.
3030
-s Strip debug info (default).
3131
-g Keep debug info.
32+
-W Generate 32 bit (non-GC64) bytecode.
33+
-X Generate 64 bit (GC64) bytecode.
34+
-d Generate bytecode in deterministic manner.
3235
-n name Set module name (default: auto-detect from input name).
3336
-t type Set output file type (default: auto-detect from output name).
3437
-a arch Override architecture for object files (default: native).
@@ -51,8 +54,9 @@ local function check(ok, ...)
5154
end
5255

5356
local function readfile(ctx, input)
54-
if type(input) == "function" then return input end
55-
if ctx.filename then
57+
if ctx.string then
58+
return check(loadstring(input, nil, ctx.mode))
59+
elseif ctx.filename then
5660
local data
5761
if input == "-" then
5862
data = io.stdin:read("*a")
@@ -61,10 +65,10 @@ local function readfile(ctx, input)
6165
data = assert(fp:read("*a"))
6266
assert(fp:close())
6367
end
64-
return check(load(data, ctx.filename))
68+
return check(load(data, ctx.filename, ctx.mode))
6569
else
6670
if input == "-" then input = nil end
67-
return check(loadfile(input))
71+
return check(loadfile(input, ctx.mode))
6872
end
6973
end
7074

@@ -624,7 +628,7 @@ end
624628

625629
local function bcsave(ctx, input, output)
626630
local f = readfile(ctx, input)
627-
local s = string.dump(f, ctx.strip)
631+
local s = string.dump(f, ctx.mode)
628632
local t = ctx.type
629633
if not t then
630634
t = detecttype(output)
@@ -647,9 +651,11 @@ local function docmd(...)
647651
local n = 1
648652
local list = false
649653
local ctx = {
650-
strip = true, arch = jit.arch, os = jit.os:lower(),
651-
type = false, modname = false,
654+
mode = "bt", arch = jit.arch, os = jit.os:lower(),
655+
type = false, modname = false, string = false,
652656
}
657+
local strip = "s"
658+
local gc64 = ""
653659
while n <= #arg do
654660
local a = arg[n]
655661
if type(a) == "string" and a:sub(1, 1) == "-" and a ~= "-" then
@@ -660,14 +666,18 @@ local function docmd(...)
660666
if opt == "l" then
661667
list = true
662668
elseif opt == "s" then
663-
ctx.strip = true
669+
strip = "s"
664670
elseif opt == "g" then
665-
ctx.strip = false
671+
strip = ""
672+
elseif opt == "W" or opt == "X" then
673+
gc64 = opt
674+
elseif opt == "d" then
675+
ctx.mode = ctx.mode .. opt
666676
else
667677
if arg[n] == nil or m ~= #a then usage() end
668678
if opt == "e" then
669679
if n ~= 1 then usage() end
670-
arg[1] = check(loadstring(arg[1]))
680+
ctx.string = true
671681
elseif opt == "n" then
672682
ctx.modname = checkmodname(tremove(arg, n))
673683
elseif opt == "t" then
@@ -687,6 +697,7 @@ local function docmd(...)
687697
n = n + 1
688698
end
689699
end
700+
ctx.mode = ctx.mode .. strip .. gc64
690701
if list then
691702
if #arg == 0 or #arg > 2 then usage() end
692703
bclist(ctx, arg[1], arg[2] or "-")

src/lib_base.c

+5-1
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,11 @@ LJLIB_ASM_(xpcall) LJLIB_REC(.)
360360
static int load_aux(lua_State *L, int status, int envarg)
361361
{
362362
if (status == LUA_OK) {
363-
if (tvistab(L->base+envarg-1)) {
363+
/*
364+
** Set environment table for top-level function.
365+
** Don't do this for non-native bytecode, which returns a prototype.
366+
*/
367+
if (tvistab(L->base+envarg-1) && tvisfunc(L->top-1)) {
364368
GCfunc *fn = funcV(L->top-1);
365369
GCtab *t = tabV(L->base+envarg-1);
366370
setgcref(fn->c.env, obj2gco(t));

0 commit comments

Comments
 (0)